minor
[cdmlib-apps.git] / cdm-eflora / src / main / java / eu / etaxonomy / cdm / io / eflora / centralAfrica / checklist / CentralAfricaChecklistTaxonImport.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 package eu.etaxonomy.cdm.io.eflora.centralAfrica.checklist;
10
11 import java.sql.ResultSet;
12 import java.sql.SQLException;
13 import java.util.HashMap;
14 import java.util.HashSet;
15 import java.util.Map;
16 import java.util.Set;
17 import java.util.UUID;
18
19 import org.apache.commons.lang.StringUtils;
20 import org.apache.logging.log4j.LogManager;
21 import org.apache.logging.log4j.Logger;
22 import org.springframework.stereotype.Component;
23
24 import eu.etaxonomy.cdm.api.service.IClassificationService;
25 import eu.etaxonomy.cdm.common.CdmUtils;
26 import eu.etaxonomy.cdm.io.common.IOValidator;
27 import eu.etaxonomy.cdm.io.common.ResultSetPartitioner;
28 import eu.etaxonomy.cdm.io.common.TdwgAreaProvider;
29 import eu.etaxonomy.cdm.io.common.mapping.DbImportMapping;
30 import eu.etaxonomy.cdm.io.common.mapping.DbImportMarkerMapper;
31 import eu.etaxonomy.cdm.io.common.mapping.DbImportObjectCreationMapper;
32 import eu.etaxonomy.cdm.io.common.mapping.DbImportTaxIncludedInMapper;
33 import eu.etaxonomy.cdm.io.common.mapping.IMappingImport;
34 import eu.etaxonomy.cdm.io.eflora.centralAfrica.checklist.validation.CentralAfricaChecklistTaxonImportValidator;
35 import eu.etaxonomy.cdm.model.common.CdmBase;
36 import eu.etaxonomy.cdm.model.description.Distribution;
37 import eu.etaxonomy.cdm.model.description.PresenceAbsenceTerm;
38 import eu.etaxonomy.cdm.model.description.TaxonDescription;
39 import eu.etaxonomy.cdm.model.location.NamedArea;
40 import eu.etaxonomy.cdm.model.name.IBotanicalName;
41 import eu.etaxonomy.cdm.model.name.Rank;
42 import eu.etaxonomy.cdm.model.name.TaxonNameFactory;
43 import eu.etaxonomy.cdm.model.reference.OriginalSourceType;
44 import eu.etaxonomy.cdm.model.reference.Reference;
45 import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
46 import eu.etaxonomy.cdm.model.taxon.Classification;
47 import eu.etaxonomy.cdm.model.taxon.Taxon;
48 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
49 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
50 import eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl;
51
52 /**
53 * @author a.mueller
54 * @since 20.02.2010
55 */
56 @Component
57 public class CentralAfricaChecklistTaxonImport
58 extends CentralAfricaChecklistImportBase<TaxonBase>
59 implements IMappingImport<TaxonBase, CentralAfricaChecklistImportState>{
60
61 private static final long serialVersionUID = 2070937718714283237L;
62 private static Logger logger = LogManager.getLogger();
63
64 private NonViralNameParserImpl parser = NonViralNameParserImpl.NewInstance();
65
66 private Map<UUID, Taxon> higherTaxonMap;
67
68 private Integer TREE_ID = null;
69
70 private DbImportMapping<?,?> mapping;
71
72 private int modCount = 10000;
73 private static final String pluralString = "taxa";
74 private static final String dbTableName = "checklist";
75 private static final Class cdmTargetClass = TaxonBase.class;
76 private static final String strOrderBy = " ORDER BY family, genus, species ";
77
78 public CentralAfricaChecklistTaxonImport(){
79 super(pluralString, dbTableName, cdmTargetClass);
80 }
81
82 @Override
83 protected String getIdQuery() {
84 String strQuery = " SELECT pk FROM " + dbTableName +
85 strOrderBy;
86 return strQuery;
87 }
88
89 @Override
90 protected DbImportMapping getMapping() {
91 if (mapping == null){
92 mapping = new DbImportMapping<>();
93
94 mapping.addMapper(DbImportObjectCreationMapper.NewInstance(this, "pk", TAXON_NAMESPACE)); //id + tu_status
95
96 UUID uuidKew = CentralAfricaChecklistTransformer.uuidAcceptedKew;
97 mapping.addMapper(DbImportMarkerMapper.NewInstance("accepted kew", uuidKew, "Accepted Kew", "Accepted Kew", "Kew", null));
98
99 UUID uuidGeneva = CentralAfricaChecklistTransformer.uuidAcceptedGeneva;
100 mapping.addMapper(DbImportMarkerMapper.NewInstance("accepted geneva", uuidGeneva, "Accepted Geneva", "Accepted Geneva", "Geneva", null));
101
102 UUID uuidItis = CentralAfricaChecklistTransformer.uuidAcceptedItis;
103 mapping.addMapper(DbImportMarkerMapper.NewInstance("accepted itis", uuidItis, "Accepted ITIS", "Accepted ITIS", "ITIS", null));
104 }
105
106 return mapping;
107 }
108
109 @Override
110 protected String getRecordQuery(CentralAfricaChecklistImportConfigurator config) {
111 String strSelect = " SELECT * ";
112 String strFrom = " FROM checklist";
113 String strWhere = " WHERE ( pk IN (" + ID_LIST_TOKEN + ") )";
114 String strRecordQuery = strSelect + strFrom + strWhere + strOrderBy;
115 return strRecordQuery;
116 }
117
118 @Override
119 public boolean doPartition(ResultSetPartitioner partitioner, CentralAfricaChecklistImportState state) {
120 higherTaxonMap = new HashMap<UUID, Taxon>();
121 Reference genevaReference = getReferenceService().find(state.getConfig().getUuidGenevaReference());
122 if (genevaReference == null){
123 genevaReference = makeGenevaReference(state);
124 getReferenceService().save(genevaReference);
125 }
126 state.setGenevaReference(genevaReference);
127 boolean success = super.doPartition(partitioner, state);
128 higherTaxonMap = new HashMap<UUID, Taxon>();
129 state.setGenevaReference(null);
130 return success;
131 }
132
133 @Override
134 public Map<Object, Map<String, ? extends CdmBase>> getRelatedObjectsForPartition(ResultSet rs, CentralAfricaChecklistImportState state) {
135 String nameSpace;
136 Class<Reference> cdmClass;
137 Set<String> idSet;
138 Set<String> referenceIdSet = new HashSet<String>();
139
140 Map<Object, Map<String, ? extends CdmBase>> result = new HashMap<Object, Map<String, ? extends CdmBase>>();
141
142 try{
143 while (rs.next()){
144 handleForeignKey(rs, referenceIdSet, "source");
145 }
146
147 //reference map
148 nameSpace = REFERENCE_NAMESPACE;
149 cdmClass = Reference.class;
150 idSet = referenceIdSet;
151 Map<String, Reference> referenceMap = getCommonService().getSourcedObjectsByIdInSourceC(cdmClass, referenceIdSet, nameSpace);
152 result.put(REFERENCE_NAMESPACE, referenceMap);
153
154 } catch (SQLException e) {
155 throw new RuntimeException(e);
156 }
157 return result;
158 }
159
160 @Override
161 public TaxonBase<?> createObject(ResultSet rs, CentralAfricaChecklistImportState state) throws SQLException {
162 IBotanicalName speciesName = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
163
164 Reference sec = state.getConfig().getSourceReference();
165 getReferenceService().saveOrUpdate(sec);
166
167 String familyString = rs.getString("family");
168 String genusString = rs.getString("genus");
169 String speciesString = rs.getString("species");
170 String authorityString = rs.getString("authority");
171
172 if (logger.isDebugEnabled()){
173 System.out.println(familyString + " " + genusString + " " + speciesString);
174 }
175
176 Taxon speciesTaxon = Taxon.NewInstance(speciesName, sec);;
177 speciesName.setGenusOrUninomial(genusString);
178 speciesName.setSpecificEpithet(speciesString);
179 parser.handleAuthors(speciesName, CdmUtils.concat(" ", new String[] {"", genusString, speciesString, authorityString}), authorityString);
180
181 //family
182 Taxon familyTaxon = null;
183 if (StringUtils.isNotBlank(familyString)){
184 familyTaxon = getHigherTaxon(state, familyString, null);
185 if (familyTaxon == null){
186 IBotanicalName familyName = TaxonNameFactory.NewBotanicalInstance(Rank.FAMILY());
187 familyName.setGenusOrUninomial(familyString);
188 familyTaxon = Taxon.NewInstance(familyName, sec);
189 saveHigherTaxon(state, familyTaxon, familyString, null);
190 }
191 getTaxonService().saveOrUpdate(familyTaxon);
192 }
193
194
195 //genus
196 Taxon genusTaxon = getHigherTaxon(state, familyString, genusString);
197 if (genusTaxon == null){
198 IBotanicalName genusName = TaxonNameFactory.NewBotanicalInstance(Rank.GENUS());
199 genusName.setGenusOrUninomial(genusString);
200 genusTaxon = Taxon.NewInstance(genusName, sec);
201 saveHigherTaxon(state, genusTaxon, familyString, genusString);
202 if (familyTaxon != null){
203 makeTaxonomicallyIncluded(state, TREE_ID, genusTaxon, familyTaxon, null, null);
204 }
205 }
206 makeTaxonomicallyIncluded(state, TREE_ID, speciesTaxon, genusTaxon, null, null);
207 getTaxonService().saveOrUpdate(genusTaxon);
208
209 String sourceString = rs.getString("source");
210 String sourceId = rs.getString("source_id");
211
212 Reference sourceRef = state.getRelatedObject(REFERENCE_NAMESPACE, sourceString, Reference.class);
213 speciesTaxon.addSource(OriginalSourceType.Import, sourceId, REFERENCE_NAMESPACE, sourceRef, null);
214
215 //geneva id
216 Reference genevaReference = state.getGenevaReference();
217 Object genevaId = rs.getObject("geneva_ID");
218 speciesTaxon.addSource(OriginalSourceType.Import, String.valueOf(genevaId), null, genevaReference, null);
219
220 //distribution
221 handleDistribution(rs, speciesTaxon);
222
223 return speciesTaxon;
224 }
225
226 private void handleDistribution(ResultSet rs, Taxon speciesTaxon) throws SQLException {
227 TaxonDescription description = TaxonDescription.NewInstance(speciesTaxon);
228
229 Boolean isCongo = rs.getBoolean("drc");
230 Boolean isBurundi = rs.getBoolean("burundi");
231 Boolean isRwanda = rs.getBoolean("rwanda");
232
233 addDistribution(description, isCongo, "ZAI");
234 addDistribution(description, isBurundi, "BUR");
235 addDistribution(description, isRwanda, "RWA");
236
237 }
238
239
240
241 /**
242 * @param description
243 * @param isCongo
244 */
245 private void addDistribution(TaxonDescription description, Boolean exists, String label) {
246 if (exists == true){
247 NamedArea namedArea = TdwgAreaProvider.getAreaByTdwgAbbreviation(label);
248 Distribution distribution = Distribution.NewInstance(namedArea, PresenceAbsenceTerm.PRESENT());
249 description.addElement(distribution);
250 }
251 }
252
253
254
255 private void saveHigherTaxon(CentralAfricaChecklistImportState state, Taxon higherTaxon, String family, String genus) {
256 String higherName = normalizeHigherTaxonName(family, genus);
257 UUID uuid = higherTaxon.getUuid();
258 state.putHigherTaxon(higherName, uuid);
259 higherTaxonMap.put(uuid, higherTaxon);
260 }
261
262
263
264 private Taxon getHigherTaxon(CentralAfricaChecklistImportState state, String family, String genus) {
265 String higherName = normalizeHigherTaxonName(family, genus);
266 UUID uuid = state.getHigherTaxon(higherName);
267
268 Taxon taxon = null;
269 if (uuid != null){
270 taxon = higherTaxonMap.get(uuid);
271 if (taxon == null){
272 taxon = CdmBase.deproxy(getTaxonService().find(uuid), Taxon.class);
273 }
274 }
275 return taxon;
276 }
277
278
279
280 /**
281 * @param family
282 * @param genus
283 */
284 private String normalizeHigherTaxonName(String family, String genus) {
285 return (CdmUtils.Nz(family) + "-" + CdmUtils.Nz(genus)).trim();
286 }
287
288
289
290
291 // private boolean makeTaxonomicallyIncluded(CentralAfricaChecklistImportState state, Taxon parent, Taxon child, Reference citation, String microCitation){
292 // Reference sec = child.getSec();
293 // UUID uuid = state.getTreeUuid(sec);
294 // Classification tree;
295 // tree = state.getTree(sec);
296 //
297 // if (tree == null){
298 // tree = makeTreeMemSave(state, sec);
299 // }
300 // TaxonNode childNode;
301 // if (parent != null){
302 // childNode = tree.addParentChild(parent, child, citation, microCitation);
303 // }else{
304 // childNode = tree.addChildTaxon(child, citation, microCitation, null);
305 // }
306 // return (childNode != null);
307 // }
308
309 //TODO use Mapper
310 private boolean makeTaxonomicallyIncluded(CentralAfricaChecklistImportState state, Integer treeRefFk, Taxon child, Taxon parent, Reference citation, String microCitation){
311 String treeKey;
312 UUID treeUuid;
313 if (treeRefFk == null){
314 treeKey = "1"; // there is only one tree and it gets the map key '1'
315 treeUuid = state.getConfig().getClassificationUuid();
316 }else{
317 treeKey =String.valueOf(treeRefFk);
318 treeUuid = state.getTreeUuidByTreeKey(treeKey);
319 }
320 Classification tree = (Classification)state.getRelatedObject(DbImportTaxIncludedInMapper.TAXONOMIC_TREE_NAMESPACE, treeKey);
321 if (tree == null){
322 IClassificationService service = state.getCurrentIO().getClassificationService();
323 tree = service.find(treeUuid);
324 if (tree == null){
325 String treeName = state.getConfig().getClassificationName();
326 tree = Classification.NewInstance(treeName);
327 tree.setUuid(treeUuid);
328 //FIXME tree reference
329 //tree.setReference(ref);
330 service.save(tree);
331 }
332 state.addRelatedObject(DbImportTaxIncludedInMapper.TAXONOMIC_TREE_NAMESPACE, treeKey, tree);
333 }
334
335 TaxonNode childNode = tree.addParentChild(parent, child, citation, microCitation);
336 return (childNode != null);
337 }
338
339
340 private Reference makeGenevaReference(CentralAfricaChecklistImportState state) {
341 Reference result = ReferenceFactory.newDatabase();
342 result.setTitleCache(state.getConfig().getGenevaReferenceTitle(), true);
343 result.setUuid(state.getConfig().getUuidGenevaReference());
344 return result;
345 }
346
347 @Override
348 protected boolean doCheck(CentralAfricaChecklistImportState state){
349 IOValidator<CentralAfricaChecklistImportState> validator = new CentralAfricaChecklistTaxonImportValidator();
350 return validator.validate(state);
351 }
352
353 @Override
354 protected boolean isIgnore(CentralAfricaChecklistImportState state){
355 return ! state.getConfig().isDoTaxa();
356 }
357
358
359
360 }