Project

General

Profile

Download (13 KB) Statistics
| Branch: | Revision:
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.IExportConfigurator.DO_REFERENCES;
22
import eu.etaxonomy.cdm.io.common.mapping.out.MethodMapper;
23
import eu.etaxonomy.cdm.model.common.CdmBase;
24
import eu.etaxonomy.cdm.model.common.DescriptionElementSource;
25
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
26
import eu.etaxonomy.cdm.model.description.TaxonDescription;
27
import eu.etaxonomy.cdm.model.description.TextData;
28
import eu.etaxonomy.cdm.model.name.TaxonNameBase;
29
import eu.etaxonomy.cdm.model.reference.Reference;
30
import eu.etaxonomy.cdm.model.taxon.Taxon;
31
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
32

    
33
/**
34
 * 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>
35
 * Inserts into DataWarehouse database table <code>AdditionalTaxonSource</code>.
36
 * @author e.-m.lee
37
 * @date 23.02.2010
38
 *
39
 */
40
@Component
41
@SuppressWarnings("unchecked")
42
public class PesiAdditionalTaxonSourceExport extends PesiExportBase {
43
	private static final Logger logger = Logger.getLogger(PesiAdditionalTaxonSourceExport.class);
44
	private static final Class<? extends CdmBase> standardMethodParameter = Reference.class;
45

    
46
	private static int modCount = 1000;
47
	private static final String dbTableName = "AdditionalTaxonSource";
48
	private static final String pluralString = "DescriptionElements";
49
	private static final String parentPluralString = "Taxa";
50
	private static boolean sourceUse_AdditionalSource = false;
51
	private static boolean sourceUse_NomenclaturalReference = false;
52
	private static boolean sourceUse_SourceOfSynonymy = false;
53
	private static TaxonNameBase currentTaxonName = null;
54
	private static String citationMicroReference = null;
55
	
56
	public PesiAdditionalTaxonSourceExport() {
57
		super();
58
	}
59

    
60
	/* (non-Javadoc)
61
	 * @see eu.etaxonomy.cdm.io.common.DbExportBase#getStandardMethodParameter()
62
	 */
63
	@Override
64
	public Class<? extends CdmBase> getStandardMethodParameter() {
65
		return standardMethodParameter;
66
	}
67

    
68
	/* (non-Javadoc)
69
	 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doCheck(eu.etaxonomy.cdm.io.common.IoStateBase)
70
	 */
71
	@Override
72
	protected boolean doCheck(PesiExportState state) {
73
		boolean result = true;
74
		return result;
75
	}
76

    
77
	/* (non-Javadoc)
78
	 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doInvoke(eu.etaxonomy.cdm.io.common.IoStateBase)
79
	 */
80
	@Override
81
	protected void doInvoke(PesiExportState state) {
82
		try {
83
			logger.error("*** Started Making " + pluralString + " ...");
84

    
85
			// Get the limit for objects to save within a single transaction.
86
//			int limit = state.getConfig().getLimitSave();
87
			int limit = 1000;
88

    
89
			// Stores whether this invoke was successful or not.
90
			boolean success = true;
91
	
92
			// PESI: Clear the database table Note.
93
			doDelete(state);
94
	
95
			// CDM: Get the number of all available description elements.
96
//			int maxCount = getDescriptionService().count(null);
97
//			logger.error("Total amount of " + maxCount + " " + pluralString + " will be exported.");
98

    
99
			// Get specific mappings: (CDM) DescriptionElement -> (PESI) Note
100
			PesiExportMapping mapping = getMapping();
101
	
102
			// Initialize the db mapper
103
			mapping.initialize(state);
104
	
105
			// PESI: Create the Notes
106
			int count = 0;
107
			int taxonCount = 0;
108
			int pastCount = 0;
109
			TransactionStatus txStatus = null;
110
			List<TaxonBase> list = null;
111

    
112
			// Start transaction
113
			txStatus = startTransaction(true);
114
			logger.error("Started new transaction. Fetching some " + parentPluralString + " first (max: " + limit + ") ...");
115
			while ((list = getTaxonService().list(null, limit, taxonCount, null, null)).size() > 0) {
116

    
117
				taxonCount += list.size();
118
				logger.error("Fetched " + list.size() + " " + parentPluralString + ".");
119
				
120
				logger.error("PHASE 2: Check for SourceUse 'Additional Source'");
121
				sourceUse_AdditionalSource = true;
122
				for (TaxonBase taxonBase : list) {
123
					
124
					// Set the current Taxon
125
					currentTaxonName = taxonBase.getName();
126

    
127
					if (taxonBase.isInstanceOf(Taxon.class)) {
128
						
129
						Taxon taxon = CdmBase.deproxy(taxonBase, Taxon.class);
130

    
131
						// Determine the TaxonDescriptions
132
						Set<TaxonDescription> taxonDescriptions = taxon.getDescriptions();
133

    
134
						// Determine the DescriptionElements (Citations) for the current Taxon
135
						for (TaxonDescription taxonDescription : taxonDescriptions) {
136
							Set<DescriptionElementBase> descriptionElements = taxonDescription.getElements();
137
							
138
							for (DescriptionElementBase descriptionElement : descriptionElements) {
139
								// According to FaEu Import those DescriptionElementBase elements are of instance TextData
140
								// There are no other indicators
141
								if (descriptionElement.isInstanceOf(TextData.class)) {
142
									Set<DescriptionElementSource> elementSources = descriptionElement.getSources();
143
									
144
									for (DescriptionElementSource elementSource : elementSources) {
145
										
146
										// Set the CitationMicroReference so it is accessible later in getSourceDetail()
147
										setCitationMicroReference(elementSource.getCitationMicroReference());
148
	
149
										// Get the citation
150
										Reference reference = elementSource.getCitation();
151
										
152
										// Check whether it was a synonym originally
153
										TaxonNameBase nameUsedInSource = elementSource.getNameUsedInSource();
154
										if (nameUsedInSource != null) {
155
											// It was a synonym originally: Set currentTaxonName to synonym's taxonName
156
											currentTaxonName = nameUsedInSource;
157
										}
158
										
159
										// Citations can be empty (null): Is it wrong data or just a normal case?
160
										if (reference != null) {
161
											if (neededValuesNotNull(reference, state)) {
162
												doCount(count++, modCount, pluralString);
163
												success &= mapping.invoke(reference);
164
											}
165
										}
166
									}
167
								}
168
							}
169
						}
170
					}
171
					
172
				}
173
				sourceUse_AdditionalSource = false;
174
				logger.error("Exported " + (count - pastCount) + " " + pluralString + ".");
175
				
176
				// Commit transaction
177
				commitTransaction(txStatus);
178
				logger.error("Committed transaction.");
179
				logger.error("Exported " + (count - pastCount) + " " + pluralString + ". Total: " + count);
180
				pastCount = count;
181

    
182
				// Start transaction
183
				txStatus = startTransaction(true);
184
				logger.error("Started new transaction. Fetching some " + parentPluralString + " first (max: " + limit + ") ...");
185
			}
186
			if (list.size() == 0) {
187
				logger.error("No " + pluralString + " left to fetch.");
188
			}
189
			// Commit transaction
190
			commitTransaction(txStatus);
191
			logger.error("Committed transaction.");
192
	
193
			logger.error("*** Finished Making " + pluralString + " ..." + getSuccessString(success));
194
			
195
			return;
196
		} catch (SQLException e) {
197
			e.printStackTrace();
198
			logger.error(e.getMessage());
199
			state.setUnsuccessfull();
200
			return;
201
		}
202
	}
203

    
204
	/**
205
	 * Checks whether needed values for an entity are NULL.
206
	 * @return
207
	 */
208
	private boolean neededValuesNotNull(Reference<?> reference, PesiExportState state) {
209
		boolean result = true;
210
		if (getSourceFk(reference, state) == null) {
211
			logger.error("SourceFk is NULL, but is not allowed to be. Therefore no record was written to export database for this reference: " + reference.getUuid());
212
			result = false;
213
		}
214
		if (getSourceUseFk(reference) == null) {
215
			logger.error("SourceUseFk is NULL, but is not allowed to be. Therefore no record was written to export database for this reference: " + reference.getUuid());
216
			result = false;
217
		}
218
		return result;
219
	}
220
	
221
	/**
222
	 * Deletes all entries of database tables related to <code>AdditionalTaxonSource</code>.
223
	 * @param state The {@link PesiExportState PesiExportState}.
224
	 * @return Whether the delete operation was successful or not.
225
	 */
226
	protected boolean doDelete(PesiExportState state) {
227
		PesiExportConfigurator pesiConfig = state.getConfig();
228
		
229
		String sql;
230
		Source destination =  pesiConfig.getDestination();
231

    
232
		// Clear AdditionalTaxonSource
233
		sql = "DELETE FROM " + dbTableName;
234
		destination.setQuery(sql);
235
		destination.update(sql);
236
		return true;
237
	}
238

    
239
	/* (non-Javadoc)
240
	 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#isIgnore(eu.etaxonomy.cdm.io.common.IoStateBase)
241
	 */
242
	@Override
243
	protected boolean isIgnore(PesiExportState state) {
244
		return ! ( state.getConfig().isDoAdditionalTaxonSource());
245
	}
246

    
247
	/**
248
	 * Returns the <code>TaxonFk</code> attribute.
249
	 * @param reference The {@link Reference Reference}.
250
	 * @see MethodMapper
251
	 */
252
	@SuppressWarnings("unused")
253
	private static Integer getTaxonFk(Reference<?> reference, PesiExportState state) {
254
		// Reference parameter isn't needed, but the DbSingleAttributeExportMapperBase throws a type mismatch exception otherwise
255
		// since it awaits two parameters if one of them is of instance DbExportStateBase.
256
		Integer result = null;
257
		if (state != null && currentTaxonName != null) {
258
			result = state.getDbId(currentTaxonName);
259
		}
260
		return result;
261
	}
262
	
263
	/**
264
	 * Returns the <code>SourceFk</code> attribute.
265
	 * @param reference The {@link Reference Reference}.
266
	 * @return The <code>SourceFk</code> attribute.
267
	 * @see MethodMapper
268
	 */
269
	private static Integer getSourceFk(Reference<?> reference, PesiExportState state) {
270
		Integer result = null;
271
		if (state != null && reference != null) {
272
			result = state.getDbId(reference);
273
		}
274
		return result;
275
	}
276
	
277
	/**
278
	 * Returns the <code>SourceUseFk</code> attribute.
279
	 * @param reference The {@link Reference Reference}.
280
	 * @return The <code>SourceUseFk</code> attribute.
281
	 * @see MethodMapper
282
	 */
283
	private static Integer getSourceUseFk(Reference<?> reference) {
284
		// TODO
285
		Integer result = null;
286
		if (sourceUse_AdditionalSource) {
287
			result = PesiTransformer.sourceUseIdSourceUseId(3);
288
		} else if (sourceUse_SourceOfSynonymy) {
289
			result = PesiTransformer.sourceUseIdSourceUseId(4);
290
		} else if (sourceUse_NomenclaturalReference) {
291
			result = PesiTransformer.sourceUseIdSourceUseId(8);
292
		}
293
		return result;
294
	}
295
	
296
	/**
297
	 * Returns the <code>SourceUseCache</code> attribute.
298
	 * @param reference The {@link Reference Reference}.
299
	 * @return The <code>SourceUseCache</code> attribute.
300
	 * @see MethodMapper
301
	 */
302
	@SuppressWarnings("unused")
303
	private static String getSourceUseCache(Reference<?> reference) {
304
		// TODO
305
		String result = null;
306
		if (sourceUse_AdditionalSource) {
307
			result = PesiTransformer.sourceUseId2SourceUseCache(3);
308
		} else if (sourceUse_SourceOfSynonymy) {
309
			result = PesiTransformer.sourceUseId2SourceUseCache(4);
310
		} else if (sourceUse_NomenclaturalReference) {
311
			result = PesiTransformer.sourceUseId2SourceUseCache(8);
312
		}
313
		return result;
314
	}
315
	
316
	/**
317
	 * Returns the <code>SourceNameCache</code> attribute.
318
	 * @param reference The {@link Reference Reference}.
319
	 * @return The <code>SourceNameCache</code> attribute.
320
	 * @see MethodMapper
321
	 */
322
	@SuppressWarnings("unused")
323
	private static String getSourceNameCache(Reference<?> reference) {
324
		String result = null;
325
		if (reference != null) {
326
			result = reference.getTitle();
327
		}
328
		return result;
329
	}
330
	
331
	/**
332
	 * Returns the <code>SourceDetail</code> attribute.
333
	 * @param reference The {@link Reference Reference}.
334
	 * @return The <code>SourceDetail</code> attribute.
335
	 * @see MethodMapper
336
	 */
337
	@SuppressWarnings("unused")
338
	private static String getSourceDetail(Reference<?> reference) {
339
		return PesiAdditionalTaxonSourceExport.citationMicroReference;
340
	}
341

    
342
	/**
343
	 * @param citationMicroReference the citationMicroReference to set
344
	 */
345
	public static void setCitationMicroReference(String citationMicroReference) {
346
		PesiAdditionalTaxonSourceExport.citationMicroReference = citationMicroReference;
347
	}
348

    
349
	/**
350
	 * Returns the CDM to PESI specific export mappings.
351
	 * @return The {@link PesiExportMapping PesiExportMapping}.
352
	 */
353
	private PesiExportMapping getMapping() {
354
		PesiExportMapping mapping = new PesiExportMapping(dbTableName);
355
		
356
		mapping.addMapper(MethodMapper.NewInstance("TaxonFk", this.getClass(), "getTaxonFk", standardMethodParameter, PesiExportState.class));
357
		mapping.addMapper(MethodMapper.NewInstance("SourceFk", this.getClass(), "getSourceFk", standardMethodParameter, PesiExportState.class));
358
		mapping.addMapper(MethodMapper.NewInstance("SourceUseFk", this));
359
		mapping.addMapper(MethodMapper.NewInstance("SourceUseCache", this));
360
		mapping.addMapper(MethodMapper.NewInstance("SourceNameCache", this));
361
		mapping.addMapper(MethodMapper.NewInstance("SourceDetail", this));
362
		
363
		return mapping;
364
	}
365

    
366
}
(1-1/15)