include infrageneric/-specific taxon and combIned
[cdmlib-apps.git] / cdm-pesi / src / main / java / eu / etaxonomy / cdm / io / pesi / out / PesiAdditionalTaxonSourceExport.java
1 // $Id$
2 /**
3 * Copyright (C) 2009 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
9 */
10 package eu.etaxonomy.cdm.io.pesi.out;
11
12 import java.sql.SQLException;
13 import java.util.List;
14 import java.util.Set;
15
16 import org.apache.log4j.Logger;
17 import org.springframework.stereotype.Component;
18 import org.springframework.transaction.TransactionStatus;
19
20 import eu.etaxonomy.cdm.io.common.Source;
21 import eu.etaxonomy.cdm.io.common.mapping.out.MethodMapper;
22 import eu.etaxonomy.cdm.model.common.CdmBase;
23 import eu.etaxonomy.cdm.model.common.DescriptionElementSource;
24 import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
25 import eu.etaxonomy.cdm.model.description.TaxonDescription;
26 import eu.etaxonomy.cdm.model.description.TextData;
27 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
28 import eu.etaxonomy.cdm.model.reference.Reference;
29 import eu.etaxonomy.cdm.model.taxon.Taxon;
30 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
31
32 /**
33 * The export class for additional information linked to {@link eu.etaxonomy.cdm.model.taxon.Taxon Taxa} and {@link eu.etaxonomy.cdm.model.reference.Reference References}.<p>
34 * Inserts into DataWarehouse database table <code>AdditionalTaxonSource</code>.
35 * @author e.-m.lee
36 * @date 23.02.2010
37 *
38 */
39 @Component
40 @SuppressWarnings("unchecked")
41 public class PesiAdditionalTaxonSourceExport extends PesiExportBase {
42 private static final Logger logger = Logger.getLogger(PesiAdditionalTaxonSourceExport.class);
43 private static final Class<? extends CdmBase> standardMethodParameter = Reference.class;
44
45 private static int modCount = 1000;
46 private static final String dbTableName = "AdditionalTaxonSource";
47 private static final String pluralString = "DescriptionElements";
48 private static final String parentPluralString = "Taxa";
49 private static boolean sourceUse_AdditionalSource = false;
50 private static boolean sourceUse_NomenclaturalReference = false;
51 private static boolean sourceUse_SourceOfSynonymy = false;
52 private static TaxonNameBase currentTaxonName = null;
53 private static String citationMicroReference = null;
54
55 public PesiAdditionalTaxonSourceExport() {
56 super();
57 }
58
59 /* (non-Javadoc)
60 * @see eu.etaxonomy.cdm.io.common.DbExportBase#getStandardMethodParameter()
61 */
62 @Override
63 public Class<? extends CdmBase> getStandardMethodParameter() {
64 return standardMethodParameter;
65 }
66
67 /* (non-Javadoc)
68 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doCheck(eu.etaxonomy.cdm.io.common.IoStateBase)
69 */
70 @Override
71 protected boolean doCheck(PesiExportState state) {
72 boolean result = true;
73 return result;
74 }
75
76 /* (non-Javadoc)
77 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doInvoke(eu.etaxonomy.cdm.io.common.IoStateBase)
78 */
79 @Override
80 protected void doInvoke(PesiExportState state) {
81 try {
82 logger.error("*** Started Making " + pluralString + " ...");
83
84 // Get the limit for objects to save within a single transaction.
85 // int limit = state.getConfig().getLimitSave();
86 int limit = 1000;
87
88 // Stores whether this invoke was successful or not.
89 boolean success = true;
90
91 // PESI: Clear the database table Note.
92 doDelete(state);
93
94 // CDM: Get the number of all available description elements.
95 // int maxCount = getDescriptionService().count(null);
96 // logger.error("Total amount of " + maxCount + " " + pluralString + " will be exported.");
97
98 // Get specific mappings: (CDM) DescriptionElement -> (PESI) Note
99 PesiExportMapping mapping = getMapping();
100
101 // Initialize the db mapper
102 mapping.initialize(state);
103
104 // PESI: Create the Notes
105 int count = 0;
106 int taxonCount = 0;
107 int pastCount = 0;
108 TransactionStatus txStatus = null;
109 List<TaxonBase> list = null;
110
111 // Start transaction
112 txStatus = startTransaction(true);
113 logger.error("Started new transaction. Fetching some " + parentPluralString + " first (max: " + limit + ") ...");
114 while ((list = getTaxonService().list(null, limit, taxonCount, null, null)).size() > 0) {
115
116 taxonCount += list.size();
117 logger.error("Fetched " + list.size() + " " + parentPluralString + ".");
118
119 logger.error("PHASE 2: Check for SourceUse 'Additional Source'");
120 sourceUse_AdditionalSource = true;
121 for (TaxonBase taxonBase : list) {
122
123 // Set the current Taxon
124 currentTaxonName = taxonBase.getName();
125
126 if (taxonBase.isInstanceOf(Taxon.class)) {
127
128 Taxon taxon = CdmBase.deproxy(taxonBase, Taxon.class);
129
130 // Determine the TaxonDescriptions
131 Set<TaxonDescription> taxonDescriptions = taxon.getDescriptions();
132
133 // Determine the DescriptionElements (Citations) for the current Taxon
134 for (TaxonDescription taxonDescription : taxonDescriptions) {
135 Set<DescriptionElementBase> descriptionElements = taxonDescription.getElements();
136
137 for (DescriptionElementBase descriptionElement : descriptionElements) {
138 // According to FaEu Import those DescriptionElementBase elements are of instance TextData
139 // There are no other indicators
140 if (descriptionElement.isInstanceOf(TextData.class)) {
141 Set<DescriptionElementSource> elementSources = descriptionElement.getSources();
142
143 for (DescriptionElementSource elementSource : elementSources) {
144
145 // Set the CitationMicroReference so it is accessible later in getSourceDetail()
146 setCitationMicroReference(elementSource.getCitationMicroReference());
147
148 // Get the citation
149 Reference reference = elementSource.getCitation();
150
151 // Check whether it was a synonym originally
152 TaxonNameBase nameUsedInSource = elementSource.getNameUsedInSource();
153 if (nameUsedInSource != null) {
154 // It was a synonym originally: Set currentTaxonName to synonym's taxonName
155 currentTaxonName = nameUsedInSource;
156 }
157
158 // Citations can be empty (null): Is it wrong data or just a normal case?
159 if (reference != null) {
160 if (neededValuesNotNull(reference, state)) {
161 doCount(count++, modCount, pluralString);
162 success &= mapping.invoke(reference);
163 }
164 }
165 }
166 }
167 }
168 }
169 }
170
171 }
172 sourceUse_AdditionalSource = false;
173 logger.error("Exported " + (count - pastCount) + " " + pluralString + ".");
174
175 // Commit transaction
176 commitTransaction(txStatus);
177 logger.error("Committed transaction.");
178 logger.error("Exported " + (count - pastCount) + " " + pluralString + ". Total: " + count);
179 pastCount = count;
180
181 // Start transaction
182 txStatus = startTransaction(true);
183 logger.error("Started new transaction. Fetching some " + parentPluralString + " first (max: " + limit + ") ...");
184 }
185 if (list.size() == 0) {
186 logger.error("No " + pluralString + " left to fetch.");
187 }
188 // Commit transaction
189 commitTransaction(txStatus);
190 logger.error("Committed transaction.");
191
192 logger.error("*** Finished Making " + pluralString + " ..." + getSuccessString(success));
193
194 return;
195 } catch (SQLException e) {
196 e.printStackTrace();
197 logger.error(e.getMessage());
198 state.setUnsuccessfull();
199 return;
200 }
201 }
202
203 /**
204 * Checks whether needed values for an entity are NULL.
205 * @return
206 */
207 private boolean neededValuesNotNull(Reference<?> reference, PesiExportState state) {
208 boolean result = true;
209 if (getSourceFk(reference, state) == null) {
210 logger.error("SourceFk is NULL, but is not allowed to be. Therefore no record was written to export database for this reference: " + reference.getUuid());
211 result = false;
212 }
213 if (getSourceUseFk(reference) == null) {
214 logger.error("SourceUseFk is NULL, but is not allowed to be. Therefore no record was written to export database for this reference: " + reference.getUuid());
215 result = false;
216 }
217 return result;
218 }
219
220 /**
221 * Deletes all entries of database tables related to <code>AdditionalTaxonSource</code>.
222 * @param state The {@link PesiExportState PesiExportState}.
223 * @return Whether the delete operation was successful or not.
224 */
225 protected boolean doDelete(PesiExportState state) {
226 PesiExportConfigurator pesiConfig = state.getConfig();
227
228 String sql;
229 Source destination = pesiConfig.getDestination();
230
231 // Clear AdditionalTaxonSource
232 sql = "DELETE FROM " + dbTableName;
233 destination.setQuery(sql);
234 destination.update(sql);
235 return true;
236 }
237
238 /* (non-Javadoc)
239 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#isIgnore(eu.etaxonomy.cdm.io.common.IoStateBase)
240 */
241 @Override
242 protected boolean isIgnore(PesiExportState state) {
243 // TODO
244 // return state.getConfig().isDoAdditionalTaxonSource()
245 return false;
246 }
247
248 /**
249 * Returns the <code>TaxonFk</code> attribute.
250 * @param reference The {@link Reference Reference}.
251 * @see MethodMapper
252 */
253 @SuppressWarnings("unused")
254 private static Integer getTaxonFk(Reference<?> reference, PesiExportState state) {
255 // Reference parameter isn't needed, but the DbSingleAttributeExportMapperBase throws a type mismatch exception otherwise
256 // since it awaits two parameters if one of them is of instance DbExportStateBase.
257 Integer result = null;
258 if (state != null && currentTaxonName != null) {
259 result = state.getDbId(currentTaxonName);
260 }
261 return result;
262 }
263
264 /**
265 * Returns the <code>SourceFk</code> attribute.
266 * @param reference The {@link Reference Reference}.
267 * @return The <code>SourceFk</code> attribute.
268 * @see MethodMapper
269 */
270 private static Integer getSourceFk(Reference<?> reference, PesiExportState state) {
271 Integer result = null;
272 if (state != null && reference != null) {
273 result = state.getDbId(reference);
274 }
275 return result;
276 }
277
278 /**
279 * Returns the <code>SourceUseFk</code> attribute.
280 * @param reference The {@link Reference Reference}.
281 * @return The <code>SourceUseFk</code> attribute.
282 * @see MethodMapper
283 */
284 private static Integer getSourceUseFk(Reference<?> reference) {
285 // TODO
286 Integer result = null;
287 if (sourceUse_AdditionalSource) {
288 result = PesiTransformer.sourceUseIdSourceUseId(3);
289 } else if (sourceUse_SourceOfSynonymy) {
290 result = PesiTransformer.sourceUseIdSourceUseId(4);
291 } else if (sourceUse_NomenclaturalReference) {
292 result = PesiTransformer.sourceUseIdSourceUseId(8);
293 }
294 return result;
295 }
296
297 /**
298 * Returns the <code>SourceUseCache</code> attribute.
299 * @param reference The {@link Reference Reference}.
300 * @return The <code>SourceUseCache</code> attribute.
301 * @see MethodMapper
302 */
303 @SuppressWarnings("unused")
304 private static String getSourceUseCache(Reference<?> reference) {
305 // TODO
306 String result = null;
307 if (sourceUse_AdditionalSource) {
308 result = PesiTransformer.sourceUseId2SourceUseCache(3);
309 } else if (sourceUse_SourceOfSynonymy) {
310 result = PesiTransformer.sourceUseId2SourceUseCache(4);
311 } else if (sourceUse_NomenclaturalReference) {
312 result = PesiTransformer.sourceUseId2SourceUseCache(8);
313 }
314 return result;
315 }
316
317 /**
318 * Returns the <code>SourceNameCache</code> attribute.
319 * @param reference The {@link Reference Reference}.
320 * @return The <code>SourceNameCache</code> attribute.
321 * @see MethodMapper
322 */
323 @SuppressWarnings("unused")
324 private static String getSourceNameCache(Reference<?> reference) {
325 String result = null;
326 if (reference != null) {
327 result = reference.getTitle();
328 }
329 return result;
330 }
331
332 /**
333 * Returns the <code>SourceDetail</code> attribute.
334 * @param reference The {@link Reference Reference}.
335 * @return The <code>SourceDetail</code> attribute.
336 * @see MethodMapper
337 */
338 @SuppressWarnings("unused")
339 private static String getSourceDetail(Reference<?> reference) {
340 return PesiAdditionalTaxonSourceExport.citationMicroReference;
341 }
342
343 /**
344 * @param citationMicroReference the citationMicroReference to set
345 */
346 public static void setCitationMicroReference(String citationMicroReference) {
347 PesiAdditionalTaxonSourceExport.citationMicroReference = citationMicroReference;
348 }
349
350 /**
351 * Returns the CDM to PESI specific export mappings.
352 * @return The {@link PesiExportMapping PesiExportMapping}.
353 */
354 private PesiExportMapping getMapping() {
355 PesiExportMapping mapping = new PesiExportMapping(dbTableName);
356
357 mapping.addMapper(MethodMapper.NewInstance("TaxonFk", this.getClass(), "getTaxonFk", standardMethodParameter, PesiExportState.class));
358 mapping.addMapper(MethodMapper.NewInstance("SourceFk", this.getClass(), "getSourceFk", standardMethodParameter, PesiExportState.class));
359 mapping.addMapper(MethodMapper.NewInstance("SourceUseFk", this));
360 mapping.addMapper(MethodMapper.NewInstance("SourceUseCache", this));
361 mapping.addMapper(MethodMapper.NewInstance("SourceNameCache", this));
362 mapping.addMapper(MethodMapper.NewInstance("SourceDetail", this));
363
364 return mapping;
365 }
366
367 }