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
.redlist
.gefaesspflanzen
;
12 import java
.sql
.ResultSet
;
13 import java
.sql
.SQLException
;
14 import java
.util
.HashMap
;
15 import java
.util
.HashSet
;
19 import org
.apache
.log4j
.Logger
;
20 import org
.springframework
.stereotype
.Component
;
22 import eu
.etaxonomy
.cdm
.common
.CdmUtils
;
23 import eu
.etaxonomy
.cdm
.io
.common
.DbImportBase
;
24 import eu
.etaxonomy
.cdm
.io
.common
.IPartitionedIO
;
25 import eu
.etaxonomy
.cdm
.io
.common
.ImportHelper
;
26 import eu
.etaxonomy
.cdm
.io
.common
.ResultSetPartitioner
;
27 import eu
.etaxonomy
.cdm
.io
.common
.mapping
.UndefinedTransformerMethodException
;
28 import eu
.etaxonomy
.cdm
.model
.agent
.AgentBase
;
29 import eu
.etaxonomy
.cdm
.model
.agent
.TeamOrPersonBase
;
30 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
31 import eu
.etaxonomy
.cdm
.model
.name
.BotanicalName
;
32 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalStatus
;
33 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalStatusType
;
34 import eu
.etaxonomy
.cdm
.model
.name
.Rank
;
35 import eu
.etaxonomy
.cdm
.model
.name
.TaxonNameBase
;
36 import eu
.etaxonomy
.cdm
.model
.taxon
.Synonym
;
37 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
38 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
48 @SuppressWarnings("serial")
49 public class RedListGefaesspflanzenImportNames
extends DbImportBase
<RedListGefaesspflanzenImportState
, RedListGefaesspflanzenImportConfigurator
> {
51 private static final Logger logger
= Logger
.getLogger(RedListGefaesspflanzenImportNames
.class);
53 private static final String tableName
= "Rote Liste Gefäßpflanzen";
55 private static final String pluralString
= "names";
57 public RedListGefaesspflanzenImportNames() {
58 super(tableName
, pluralString
);
62 protected String
getIdQuery(RedListGefaesspflanzenImportState state
) {
63 return "SELECT NAMNR "
64 + "FROM V_TAXATLAS_D20_EXPORT t "
69 protected String
getRecordQuery(RedListGefaesspflanzenImportConfigurator config
) {
70 String result
= " SELECT * "
71 + " FROM V_TAXATLAS_D20_EXPORT t "
72 + " WHERE t.NAMNR IN (@IDSET)";
73 result
= result
.replace("@IDSET", IPartitionedIO
.ID_LIST_TOKEN
);
78 protected void doInvoke(RedListGefaesspflanzenImportState state
) {
79 super.doInvoke(state
);
84 public boolean doPartition(ResultSetPartitioner partitioner
, RedListGefaesspflanzenImportState state
) {
85 ResultSet rs
= partitioner
.getResultSet();
86 Set
<TaxonNameBase
> namesToSave
= new HashSet
<TaxonNameBase
>();
87 Set
<TaxonBase
> taxaToSave
= new HashSet
<TaxonBase
>();
90 makeSingleNameAndTaxon(state
, rs
, namesToSave
, taxaToSave
);
93 } catch (SQLException e
) {
97 getNameService().saveOrUpdate(namesToSave
);
98 getTaxonService().saveOrUpdate(taxaToSave
);
102 private void makeSingleNameAndTaxon(RedListGefaesspflanzenImportState state
, ResultSet rs
, Set
<TaxonNameBase
> namesToSave
, Set
<TaxonBase
> taxaToSave
)
103 throws SQLException
{
104 long id
= rs
.getLong(RedListUtil
.NAMNR
);
105 String taxNameString
= rs
.getString(RedListUtil
.TAXNAME
);
106 String gueltString
= rs
.getString(RedListUtil
.GUELT
);
107 String rangString
= rs
.getString(RedListUtil
.RANG
);
108 String ep1String
= rs
.getString(RedListUtil
.EPI1
);
109 String ep2String
= rs
.getString(RedListUtil
.EPI2
);
110 String ep3String
= rs
.getString(RedListUtil
.EPI3
);
111 String nomZusatzString
= rs
.getString(RedListUtil
.NOM_ZUSATZ
);
112 String taxZusatzString
= rs
.getString(RedListUtil
.TAX_ZUSATZ
);
113 String zusatzString
= rs
.getString(RedListUtil
.ZUSATZ
);
114 String authorKombString
= rs
.getString(RedListUtil
.AUTOR_KOMB
);
115 String authorBasiString
= rs
.getString(RedListUtil
.AUTOR_BASI
);
118 if(CdmUtils
.isBlank(taxNameString
) && CdmUtils
.isBlank(ep1String
)){
119 RedListUtil
.logMessage(id
, "No name found!", logger
);
122 Rank rank
= makeRank(id
, state
, rangString
);
123 BotanicalName name
= BotanicalName
.NewInstance(rank
);
125 //ep1 should always be present
126 if(CdmUtils
.isBlank(ep1String
)){
127 RedListUtil
.logMessage(id
, RedListUtil
.EPI1
+" is empty!", logger
);
129 name
.setGenusOrUninomial(ep1String
);
130 if(CdmUtils
.isNotBlank(ep2String
)){
131 name
.setSpecificEpithet(ep2String
);
133 if(CdmUtils
.isNotBlank(ep3String
)){
134 if(rank
==Rank
.SUBSPECIES() ||
135 rank
==Rank
.VARIETY()){
136 name
.setInfraSpecificEpithet(ep3String
);
139 //nomenclatural status
140 if(CdmUtils
.isNotBlank(nomZusatzString
)){
141 NomenclaturalStatusType status
= makeNomenclaturalStatus(id
, state
, nomZusatzString
);
143 name
.addStatus(NomenclaturalStatus
.NewInstance(status
));
150 if(authorKombString
.contains(RedListUtil
.EX
)){
151 //TODO: what happens with multiple ex authors??
152 String
[] kombSplit
= authorKombString
.split(RedListUtil
.EX
);
153 if(kombSplit
.length
!=2){
154 RedListUtil
.logMessage(id
, "Multiple ex combination authors found", logger
);
156 for (int i
= 0; i
< kombSplit
.length
; i
++) {
158 //first author is ex author
159 TeamOrPersonBase authorKomb
= (TeamOrPersonBase
) state
.getRelatedObject(RedListUtil
.AUTHOR_NAMESPACE
, kombSplit
[i
]);
160 name
.setExCombinationAuthorship(authorKomb
);
163 TeamOrPersonBase authorKomb
= (TeamOrPersonBase
) state
.getRelatedObject(RedListUtil
.AUTHOR_NAMESPACE
, kombSplit
[i
]);
164 name
.setCombinationAuthorship(authorKomb
);
168 else if(authorKombString
.trim().equals(RedListUtil
.AUCT
)){
169 RedListUtil
.logMessage(id
, "AUCT information in "+RedListUtil
.AUTOR_KOMB
+" column", logger
);
171 else if(CdmUtils
.isNotBlank(authorKombString
)){
172 TeamOrPersonBase authorKomb
= (TeamOrPersonBase
) state
.getRelatedObject(RedListUtil
.AUTHOR_NAMESPACE
, authorKombString
);
173 name
.setCombinationAuthorship(authorKomb
);
176 if(authorBasiString
.contains(RedListUtil
.EX
)){
177 String
[] basiSplit
= authorBasiString
.split(RedListUtil
.EX
);
178 for (int i
= 0; i
< basiSplit
.length
; i
++) {
179 if(basiSplit
.length
!=2){
180 RedListUtil
.logMessage(id
, "Multiple ex basionymn authors found", logger
);
183 TeamOrPersonBase authorBasi
= (TeamOrPersonBase
) state
.getRelatedObject(RedListUtil
.AUTHOR_NAMESPACE
, basiSplit
[i
]);
184 if(CdmUtils
.isBlank(authorKombString
)){
185 name
.setExCombinationAuthorship(authorBasi
);
188 name
.setExBasionymAuthorship(authorBasi
);
192 TeamOrPersonBase authorBasi
= (TeamOrPersonBase
) state
.getRelatedObject(RedListUtil
.AUTHOR_NAMESPACE
, basiSplit
[i
]);
193 if(CdmUtils
.isBlank(authorKombString
)){
194 name
.setCombinationAuthorship(authorBasi
);
197 name
.setBasionymAuthorship(authorBasi
);
202 else if(CdmUtils
.isNotBlank(authorBasiString
)){
203 //this seems to be a convention in the source database: When there is only a single author then only the "AUTOR_BASI" column is used
204 TeamOrPersonBase authorBasi
= (TeamOrPersonBase
) state
.getRelatedObject(RedListUtil
.AUTHOR_NAMESPACE
, authorBasiString
);
205 if(CdmUtils
.isBlank(authorKombString
)){
206 name
.setCombinationAuthorship(authorBasi
);
209 name
.setBasionymAuthorship(authorBasi
);
213 //check authorship consistency
214 String authorString
= rs
.getString(RedListUtil
.AUTOR
);
215 String authorshipCache
= name
.getAuthorshipCache();
217 if(CdmUtils
.isNotBlank(zusatzString
)){
218 authorString
= authorString
.replace(", "+zusatzString
, "");
220 if(CdmUtils
.isNotBlank(nomZusatzString
)){
221 authorString
= authorString
.replace(", "+nomZusatzString
, "");
223 if(CdmUtils
.isNotBlank(taxZusatzString
)){
224 authorString
= authorString
.replace(", "+taxZusatzString
, "");
226 if(authorString
.equals(RedListUtil
.AUCT
)){
229 if(!authorString
.equals(authorshipCache
)){
230 RedListUtil
.logMessage(id
, "Authorship inconsistent! name.authorhshipCache <-> Column "+RedListUtil
.AUTOR
+": "+authorshipCache
+" <-> "+authorString
, logger
);
234 ImportHelper
.setOriginalSource(name
, state
.getTransactionalSourceReference(), id
, RedListUtil
.NAME_NAMESPACE
);
235 state
.getNameMap().put(id
, name
.getUuid());
237 namesToSave
.add(name
);
240 TaxonBase taxonBase
= null;
241 if(gueltString
.equals(RedListUtil
.GUELT_ACCEPTED_TAXON
) || (name
.getAppendedPhrase()!=null && authorBasiString
.trim().equals(RedListUtil
.AUCT
))){
242 taxonBase
= Taxon
.NewInstance(name
, null);
243 taxonBase
.setAppendedPhrase(authorBasiString
);
245 else if(gueltString
.equals(RedListUtil
.GUELT_SYNONYM
) || gueltString
.equals(RedListUtil
.GUELT_BASIONYM
)){
246 taxonBase
= Synonym
.NewInstance(name
, null);
249 RedListUtil
.logMessage(id
, "Taxon for name "+name
+" could not be created.", logger
);
253 taxaToSave
.add(taxonBase
);
256 ImportHelper
.setOriginalSource(taxonBase
, state
.getTransactionalSourceReference(), id
, RedListUtil
.TAXON_NAMESPACE
);
257 state
.getTaxonMap().put(id
, taxonBase
.getUuid());
260 private Rank
makeRank(long id
, RedListGefaesspflanzenImportState state
, String rankStr
) {
263 rank
= state
.getTransformer().getRankByKey(rankStr
);
264 } catch (UndefinedTransformerMethodException e
) {
268 RedListUtil
.logMessage(id
, rankStr
+" could not be associated to a known rank.", logger
);
273 private NomenclaturalStatusType
makeNomenclaturalStatus(long id
, RedListGefaesspflanzenImportState state
, String nomZusatzString
) {
274 NomenclaturalStatusType status
= null;
276 status
= state
.getTransformer().getNomenclaturalStatusByKey(nomZusatzString
);
277 } catch (UndefinedTransformerMethodException e
) {
281 RedListUtil
.logMessage(id
, nomZusatzString
+" could not be associated to a known nomenclatural status.", logger
);
289 public Map
<Object
, Map
<String
, ?
extends CdmBase
>> getRelatedObjectsForPartition(ResultSet rs
,
290 RedListGefaesspflanzenImportState state
) {
291 Map
<Object
, Map
<String
, ?
extends CdmBase
>> result
= new HashMap
<>();
292 Map
<String
, AgentBase
<?
>> authorMap
= new HashMap
<String
, AgentBase
<?
>>();
296 String authorKombString
= rs
.getString(RedListUtil
.AUTOR_KOMB
);
298 if(authorKombString
.contains(RedListUtil
.EX
)){
299 String
[] kombSplit
= authorKombString
.split(RedListUtil
.EX
);
300 for (int i
= 0; i
< kombSplit
.length
; i
++) {
301 if(!authorMap
.containsKey(kombSplit
[i
])){
302 authorMap
.put(kombSplit
[i
], getAgentService().load(state
.getAuthorMap().get(kombSplit
[i
])));
306 else if(CdmUtils
.isNotBlank(authorKombString
) && !authorMap
.containsKey(authorKombString
)){
307 authorMap
.put(authorKombString
, getAgentService().load(state
.getAuthorMap().get(authorKombString
)));
310 String authorBasiString
= rs
.getString(RedListUtil
.AUTOR_BASI
);
312 if(authorBasiString
.contains(RedListUtil
.EX
)){
313 String
[] basiSplit
= authorBasiString
.split(RedListUtil
.EX
);
314 for (int i
= 0; i
< basiSplit
.length
; i
++) {
315 if(!authorMap
.containsKey(basiSplit
[i
])){
316 authorMap
.put(basiSplit
[i
], getAgentService().load(state
.getAuthorMap().get(basiSplit
[i
])));
320 else if(CdmUtils
.isNotBlank(authorBasiString
) && !authorMap
.containsKey(authorBasiString
)){
321 authorMap
.put(authorBasiString
, getAgentService().load(state
.getAuthorMap().get(authorBasiString
)));
324 } catch (SQLException e
) {
327 result
.put(RedListUtil
.AUTHOR_NAMESPACE
, authorMap
);
333 protected boolean doCheck(RedListGefaesspflanzenImportState state
) {
338 protected boolean isIgnore(RedListGefaesspflanzenImportState state
) {