Project

General

Profile

Download (14.1 KB) Statistics
| Branch: | Revision:
1
/**
2
* Copyright (C) 2009 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.pesi.out;
10

    
11
import java.sql.SQLException;
12
import java.util.ArrayList;
13
import java.util.HashSet;
14
import java.util.List;
15
import java.util.Set;
16

    
17
import org.apache.log4j.Logger;
18
import org.springframework.stereotype.Component;
19
import org.springframework.transaction.TransactionStatus;
20

    
21
import eu.etaxonomy.cdm.io.common.IExportConfigurator.DO_REFERENCES;
22
import eu.etaxonomy.cdm.io.common.Source;
23
import eu.etaxonomy.cdm.io.common.mapping.out.DbExtensionMapper;
24
import eu.etaxonomy.cdm.io.common.mapping.out.DbStringMapper;
25
import eu.etaxonomy.cdm.io.common.mapping.out.DbTimePeriodMapper;
26
import eu.etaxonomy.cdm.io.common.mapping.out.DbUriMapper;
27
import eu.etaxonomy.cdm.io.common.mapping.out.IdMapper;
28
import eu.etaxonomy.cdm.io.common.mapping.out.MethodMapper;
29
import eu.etaxonomy.cdm.io.pesi.erms.ErmsTransformer;
30
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
31
import eu.etaxonomy.cdm.model.common.CdmBase;
32
import eu.etaxonomy.cdm.model.common.ExtensionType;
33
import eu.etaxonomy.cdm.model.common.IdentifiableSource;
34
import eu.etaxonomy.cdm.model.reference.Reference;
35
import eu.etaxonomy.cdm.model.reference.ReferenceType;
36

    
37
/**
38
 * The export class for {@link eu.etaxonomy.cdm.model.reference.Reference References}.<p>
39
 * Inserts into DataWarehouse database table <code>Source</code>.
40
 * @author e.-m.lee
41
 * @since 11.02.2010
42
 *
43
 */
44
@Component
45
public class PesiSourceExport extends PesiExportBase {
46

    
47
    private static final long serialVersionUID = -3084883718722120651L;
48
    private static final Logger logger = Logger.getLogger(PesiSourceExport.class);
49

    
50
    private static final Class<? extends CdmBase> standardMethodParameter = Reference.class;
51

    
52
	private static int modCount = 1000;
53
	public static final String dbTableName = "Source";
54
	private static final String pluralString = "Sources";
55
	List<Integer> storedSourceIds = new ArrayList<Integer>();
56

    
57
	public PesiSourceExport() {
58
		super();
59
	}
60

    
61
	@Override
62
	public Class<? extends CdmBase> getStandardMethodParameter() {
63
		return standardMethodParameter;
64
	}
65

    
66
	@Override
67
	protected boolean doCheck(PesiExportState state) {
68
		boolean result = true;
69
		return result;
70
	}
71

    
72
	/**
73
	 * Checks whether a sourceId was stored already.
74
	 * @param sourceId
75
	 * @return
76
	 */
77
	protected boolean isStoredSourceId(Integer sourceId) {
78
		if (storedSourceIds.contains(sourceId)) {
79
			return true;
80
		} else {
81
			return false;
82
		}
83
	}
84

    
85
	/**
86
	 * Adds a sourceId to the list of storedSourceIds.
87
	 * @param sourceId
88
	 */
89
	protected void addToStoredSourceIds(Integer sourceId) {
90
		if (! storedSourceIds.contains(sourceId)) {
91
			this.storedSourceIds.add(sourceId);
92
		}
93
	}
94

    
95
	@Override
96
	protected void doInvoke(PesiExportState state) {
97
		try{
98
			logger.info("*** Started Making " + pluralString + " ...");
99

    
100
			PesiExportConfigurator pesiExportConfigurator = state.getConfig();
101

    
102
			// Get the limit for objects to save within a single transaction.
103
			int limit = pesiExportConfigurator.getLimitSave();
104

    
105
			// Stores whether this invoke was successful or not.
106
			boolean success = true ;
107

    
108
			// PESI: Clear the database table Source.
109
			//doDelete(state);  -> done by stored procedure
110

    
111
			// Get specific mappings: (CDM) Reference -> (PESI) Source
112
			PesiExportMapping mapping = getMapping();
113

    
114
			// Initialize the db mapper
115
			mapping.initialize(state);
116

    
117
			// Create the Sources
118
			int count = 0;
119
			int pastCount = 0;
120
			TransactionStatus txStatus = null;
121
			List<Reference> list = null;
122

    
123
//			logger.error("PHASE 1...");
124
			// Start transaction
125
			txStatus = startTransaction(true);
126
			logger.info("Started new transaction. Fetching some " + pluralString + " (max: " + limit + ") ...");
127
			while ((list = getReferenceService().list(null, limit, count, null, null)).size() > 0) {
128

    
129
				logger.debug("Fetched " + list.size() + " " + pluralString + ". Exporting...");
130
				for (Reference reference : list) {
131
					doCount(count++, modCount, pluralString);
132
					success &= mapping.invoke(reference);
133
				}
134

    
135
				// Commit transaction
136
				commitTransaction(txStatus);
137
				logger.debug("Committed transaction.");
138
				logger.info("Exported " + (count - pastCount) + " " + pluralString + ". Total: " + count);
139
				pastCount = count;
140

    
141
				// Start transaction
142
				txStatus = startTransaction(true);
143
				logger.info("Started new transaction. Fetching some " + pluralString + " (max: " + limit + ") ...");
144
			}
145
			if (list.size() == 0) {
146
				logger.info("No " + pluralString + " left to fetch.");
147
			}
148
			// Commit transaction
149
			commitTransaction(txStatus);
150
			logger.info("Committed transaction.");
151

    
152
			logger.info("*** Finished Making " + pluralString + " ..." + getSuccessString(success));
153

    
154
			if (!success){
155
				state.getResult().addError("An error occurred in PesiSourceExport.invoke");
156
			}
157
			return;
158
		} catch (SQLException e) {
159
			e.printStackTrace();
160
			logger.error(e.getMessage());
161
			state.getResult().addException(e);
162
			return;
163
		}
164
	}
165

    
166
	/**
167
	 * Deletes all entries of database tables related to <code>Source</code>.
168
	 * @param state The {@link PesiExportState PesiExportState}.
169
	 * @return Whether the delete operation was successful or not.
170
	 */
171
	protected boolean doDelete(PesiExportState state) {
172
		PesiExportConfigurator pesiConfig = state.getConfig();
173

    
174
		String sql;
175
		Source destination =  pesiConfig.getDestination();
176

    
177
		// Clear Occurrences
178
		sql = "DELETE FROM Occurrence";
179
		destination.setQuery(sql);
180
		destination.update(sql);
181

    
182
		// Clear Taxa
183
		sql = "DELETE FROM Taxon";
184
		destination.setQuery(sql);
185
		destination.update(sql);
186

    
187
		// Clear Sources
188
		sql = "DELETE FROM " + dbTableName;
189
		destination.setQuery(sql);
190
		destination.update(sql);
191

    
192
		return true;
193
	}
194

    
195
	/**
196
	 * Returns the <code>IMIS_Id</code> attribute.
197
	 * @param reference The {@link Reference Reference}.
198
	 * @return The <code>IMIS_Id</code> attribute.
199
	 * @see MethodMapper
200
	 */
201
	@SuppressWarnings("unused")
202
	private static Integer getIMIS_Id(Reference reference) {
203
		return null;
204
	}
205

    
206
	/**
207
	 * Returns the <code>SourceCategoryFK</code> attribute.
208
	 * @param reference The {@link Reference Reference}.
209
	 * @return The <code>SourceCategoryFK</code> attribute.
210
	 * @see MethodMapper
211
	 */
212
	@SuppressWarnings("unused")
213
	private static Integer getSourceCategoryFK(Reference reference) {
214
		Integer result = null;
215
		try {
216
		result = PesiTransformer.reference2SourceCategoryFK(reference);
217
		} catch (Exception e) {
218
			e.printStackTrace();
219
		}
220
		return result;
221
	}
222

    
223
	/**
224
	 * Returns the <code>SourceCategoryCache</code> attribute.
225
	 * @param reference The {@link Reference Reference}.
226
	 * @return The <code>SourceCategoryCache</code> attribute.
227
	 * @see MethodMapper
228
	 */
229
	@SuppressWarnings("unused")
230
	private static String getSourceCategoryCache(Reference reference, PesiExportState state) {
231
		return state.getTransformer().getCacheByReference(reference);
232
	}
233

    
234
	/**
235
	 * Returns the <code>Name</code> attribute. The corresponding CDM attribute is <code>title</code>.
236
	 * @param reference The {@link Reference Reference}.
237
	 * @return The <code>Name</code> attribute.
238
	 * @see MethodMapper
239
	 */
240
	@SuppressWarnings("unused")
241
	private static String getName(Reference reference) {
242
		if (reference != null) {
243
			return reference.getTitleCache(); // was getTitle()
244
		} else {
245
			return null;
246
		}
247
	}
248

    
249
	/**
250
	 * Returns the <code>AuthorString</code> attribute. The corresponding CDM attribute is the <code>titleCache</code> of an <code>authorTeam</code>.
251
	 * @param reference The {@link Reference Reference}.
252
	 * @return The <code>AuthorString</code> attribute.
253
	 * @see MethodMapper
254
	 */
255
	@SuppressWarnings("unused")
256
	private static String getAuthorString(Reference reference) {
257
		String result = null;
258

    
259
		try {
260
		if (reference != null) {
261
			TeamOrPersonBase team = reference.getAuthorship();
262
			if (team != null) {
263
				result = team.getTitleCache();
264
//				result = team.getNomenclaturalTitle();
265
			} else {
266
				result = null;
267
			}
268
		}
269
		} catch (Exception e) {
270
			e.printStackTrace();
271
		}
272

    
273
		return result;
274
	}
275

    
276
	/**
277
	 * Returns the <code>NomRefCache</code> attribute. The corresponding CDM attribute is <code>titleCache</code>.
278
	 * @param reference The {@link Reference Reference}.
279
	 * @return The <code>NomRefCache</code> attribute.
280
	 * @see MethodMapper
281
	 */
282
	@SuppressWarnings("unused")
283
	private static String getNomRefCache(Reference reference) {
284
		return null;
285
//		if (reference != null) {
286
//			return reference.getTitleCache();
287
//		} else {
288
//			return null;
289
//		}
290
	}
291

    
292
	/**
293
	 * Returns the <code>Notes</code> attribute.
294
	 * @param reference The {@link Reference Reference}.
295
	 * @return The <code>Notes</code> attribute.
296
	 * @see MethodMapper
297
	 */
298
	@SuppressWarnings("unused")
299
	private static String getNotes(Reference reference) {
300
		// TODO
301
		return null;
302
	}
303

    
304
	/**
305
	 * Returns the <code>RefIdInSource</code> attribute.
306
	 * @param reference The {@link Reference Reference}.
307
	 * @return The <code>RefIdInSource</code> attribute.
308
	 * @see MethodMapper
309
	 */
310
	@SuppressWarnings("unused")
311
	private static String getRefIdInSource(Reference reference) {
312
		String result = null;
313

    
314
		try {
315
		if (reference != null) {
316
			Set<IdentifiableSource> sourceAll = reference.getSources();
317
			Set<IdentifiableSource> sourceCandidates = filterOriginalPesiDbSources(sourceAll);
318

    
319
			if (sourceCandidates.size() == 1) {
320
				result = sourceCandidates.iterator().next().getIdInSource();
321
			} else if (sourceCandidates.size() > 1) {
322
				logger.warn("Reference for RefIdInSource has multiple IdentifiableSources which are candidates for a PESI originalDbSource. RefIdInSource can't be determined correctly and will be left out: " + reference.getUuid() + " (" + reference.getTitleCache() + ")");
323
				int count = 1;
324
//				for (IdentifiableSource source : sources) {
325
//					result += source.getIdInSource();
326
//					if (count < sources.size()) {
327
//						result += "; ";
328
//					}
329
//					count++;
330
//				}
331
			}
332
		}
333
		} catch (Exception e) {
334
			e.printStackTrace();
335
		}
336

    
337
		return result;
338
	}
339

    
340
	private static Set<IdentifiableSource> filterOriginalPesiDbSources(
341
			Set<IdentifiableSource> sourceAll) {
342
		Set<IdentifiableSource> sourceCandidates = new HashSet<IdentifiableSource>();
343
		for (IdentifiableSource source : sourceAll){
344
			if (isOriginalPesiDbSource(source)){
345
				sourceCandidates.add(source);
346
			}
347
		}
348
		return sourceCandidates;
349
	}
350

    
351
	private static boolean isOriginalPesiDbSource(IdentifiableSource source) {
352
		return (source.getCitation() != null) &&
353
				source.getCitation().getType().equals(ReferenceType.Database);
354
	}
355

    
356
	/**
357
	 * Returns the <code>OriginalDB</code> attribute. The corresponding CDM attribute is the <code>titleCache</code> of a <code>citation</code>.
358
	 * @param reference The {@link Reference Reference}.
359
	 * @return The <code>OriginalDB</code> attribute.
360
	 * @see MethodMapper
361
	 */
362
	@SuppressWarnings("unused")
363
	private static String getOriginalDB(Reference reference) {
364
		String result = "";
365

    
366
		try {
367
		if (reference != null) {
368
			Set<IdentifiableSource> sourcesAll = reference.getSources();
369
			Set<IdentifiableSource> sourceCandidates = filterOriginalPesiDbSources(sourcesAll);
370

    
371
			if (sourceCandidates.size() == 1) {
372
				Reference citation = sourceCandidates.iterator().next().getCitation();
373
				if (citation != null) {
374
					result = PesiTransformer.databaseString2Abbreviation(citation.getTitleCache()); //or just title
375
				} else {
376
					logger.warn("OriginalDB can not be determined because the citation of this source is NULL: " + sourceCandidates.iterator().next().getUuid());
377
				}
378
			} else if (sourceCandidates.size() > 1) {
379
				logger.warn("Taxon has multiple IdentifiableSources: " + reference.getUuid() + " (" + reference.getTitleCache() + ")");
380
				int count = 1;
381
				for (IdentifiableSource source : sourceCandidates) {
382
					Reference citation = source.getCitation();
383
					if (citation != null) {
384
						result += PesiTransformer.databaseString2Abbreviation(citation.getTitleCache());
385
						if (count < sourceCandidates.size()) {
386
							result += "; ";
387
						}
388
						count++;
389
					}
390
				}
391
			} else {
392
				result = null;
393
			}
394
		}
395
		} catch (Exception e) {
396
			e.printStackTrace();
397
		}
398

    
399
		return result;
400
	}
401

    
402
	@Override
403
	protected boolean isIgnore(PesiExportState state) {
404
		return ! state.getConfig().getDoReferences().equals(DO_REFERENCES.ALL);
405
	}
406

    
407
	/**
408
	 * Returns the CDM to PESI specific export mappings.
409
	 * @return The {@link PesiExportMapping PesiExportMapping}.
410
	 */
411
	private PesiExportMapping getMapping() {
412
		PesiExportMapping mapping = new PesiExportMapping(dbTableName);
413
		ExtensionType extensionType = null;
414

    
415
		mapping.addMapper(IdMapper.NewInstance("SourceId"));
416

    
417
		// IMIS_Id
418
		extensionType = (ExtensionType)getTermService().find(ErmsTransformer.IMIS_UUID);
419
		if (extensionType != null) {
420
			mapping.addMapper(DbExtensionMapper.NewInstance(extensionType, "IMIS_Id"));
421
		} else {
422
			mapping.addMapper(MethodMapper.NewInstance("IMIS_Id", this));
423
		}
424

    
425
		mapping.addMapper(MethodMapper.NewInstance("SourceCategoryFK", this));
426
		mapping.addMapper(MethodMapper.NewInstance("SourceCategoryCache", this, Reference.class, PesiExportState.class));
427
		mapping.addMapper(MethodMapper.NewInstance("Name", this));
428
		mapping.addMapper(DbStringMapper.NewInstance("referenceAbstract", "Abstract"));
429
		mapping.addMapper(DbStringMapper.NewInstance("title", "Title"));
430
		mapping.addMapper(MethodMapper.NewInstance("AuthorString", this));
431
		mapping.addMapper(DbTimePeriodMapper.NewInstance("datePublished", "RefYear"));
432
		mapping.addMapper(MethodMapper.NewInstance("NomRefCache", this));
433
		mapping.addMapper(DbUriMapper.NewInstance("uri", "Link"));
434
		mapping.addMapper(MethodMapper.NewInstance("Notes", this));
435
		mapping.addMapper(MethodMapper.NewInstance("RefIdInSource", this));
436
		mapping.addMapper(MethodMapper.NewInstance("OriginalDB", this));
437

    
438
		return mapping;
439
	}
440
}
(10-10/12)