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.berlinModel.out.mapper.MethodMapper;
21
import eu.etaxonomy.cdm.io.common.Source;
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 = (PesiExportConfigurator) 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
}
(1-1/15)