Project

General

Profile

Download (14.5 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.ArrayList;
14
import java.util.HashSet;
15
import java.util.List;
16
import java.util.Set;
17

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

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

    
38
/**
39
 * The export class for {@link eu.etaxonomy.cdm.model.reference.Reference References}.<p>
40
 * Inserts into DataWarehouse database table <code>Source</code>.
41
 * @author e.-m.lee
42
 * @date 11.02.2010
43
 *
44
 */
45
@Component
46
public class PesiSourceExport extends PesiExportBase {
47
	private static final Logger logger = Logger.getLogger(PesiSourceExport.class);
48
	private static final Class<? extends CdmBase> standardMethodParameter = Reference.class;
49

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

    
55
	public PesiSourceExport() {
56
		super();
57
	}
58

    
59
	/* (non-Javadoc)
60
	 * @see eu.etaxonomy.cdm.io.pesi.out.PesiExportBase#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
	/**
77
	 * Checks whether a sourceId was stored already.
78
	 * @param sourceId
79
	 * @return
80
	 */
81
	protected boolean isStoredSourceId(Integer sourceId) {
82
		if (storedSourceIds.contains(sourceId)) {
83
			return true;
84
		} else {
85
			return false;
86
		}
87
	}
88

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

    
99
	/* (non-Javadoc)
100
	 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doInvoke(eu.etaxonomy.cdm.io.common.IoStateBase)
101
	 */
102
	@Override
103
	protected void doInvoke(PesiExportState state) {
104
		try{
105
			logger.info("*** Started Making " + pluralString + " ...");
106

    
107
			PesiExportConfigurator pesiExportConfigurator = state.getConfig();
108
			
109
			// Get the limit for objects to save within a single transaction.
110
			int limit = pesiExportConfigurator.getLimitSave();
111

    
112
			// Stores whether this invoke was successful or not.
113
			boolean success = true ;
114

    
115
			// PESI: Clear the database table Source.
116
			doDelete(state);
117

    
118
			// Get specific mappings: (CDM) Reference -> (PESI) Source
119
			PesiExportMapping mapping = getMapping();
120

    
121
			// Initialize the db mapper
122
			mapping.initialize(state);
123

    
124
			// Create the Sources
125
			int count = 0;
126
			int pastCount = 0;
127
			TransactionStatus txStatus = null;
128
			List<Reference> list = null;
129

    
130
//			logger.error("PHASE 1...");
131
			// Start transaction
132
			txStatus = startTransaction(true);
133
			logger.info("Started new transaction. Fetching some " + pluralString + " (max: " + limit + ") ...");
134
			while ((list = getReferenceService().list(null, limit, count, null, null)).size() > 0) {
135

    
136
				logger.debug("Fetched " + list.size() + " " + pluralString + ". Exporting...");
137
				for (Reference<?> reference : list) {
138
					doCount(count++, modCount, pluralString);
139
					success &= mapping.invoke(reference);
140
				}
141

    
142
				// Commit transaction
143
				commitTransaction(txStatus);
144
				logger.debug("Committed transaction.");
145
				logger.info("Exported " + (count - pastCount) + " " + pluralString + ". Total: " + count);
146
				pastCount = count;
147

    
148
				// Start transaction
149
				txStatus = startTransaction(true);
150
				logger.info("Started new transaction. Fetching some " + pluralString + " (max: " + limit + ") ...");
151
			}
152
			if (list.size() == 0) {
153
				logger.info("No " + pluralString + " left to fetch.");
154
			}
155
			// Commit transaction
156
			commitTransaction(txStatus);
157
			logger.info("Committed transaction.");
158
			
159
			logger.info("*** Finished Making " + pluralString + " ..." + getSuccessString(success));
160

    
161
			if (!success){
162
				state.setUnsuccessfull();
163
			}
164
			return;
165
		} catch (SQLException e) {
166
			e.printStackTrace();
167
			logger.error(e.getMessage());
168
			state.setUnsuccessfull();
169
			return;
170
		}
171
	}
172

    
173
	/**
174
	 * Deletes all entries of database tables related to <code>Source</code>.
175
	 * @param state The {@link PesiExportState PesiExportState}.
176
	 * @return Whether the delete operation was successful or not.
177
	 */
178
	protected boolean doDelete(PesiExportState state) {
179
		PesiExportConfigurator pesiConfig = (PesiExportConfigurator) state.getConfig();
180
		
181
		String sql;
182
		Source destination =  pesiConfig.getDestination();
183

    
184
		// Clear Occurrences
185
		sql = "DELETE FROM Occurrence";
186
		destination.setQuery(sql);
187
		destination.update(sql);
188

    
189
		// Clear Taxa
190
		sql = "DELETE FROM Taxon";
191
		destination.setQuery(sql);
192
		destination.update(sql);
193

    
194
		// Clear Sources
195
		sql = "DELETE FROM " + dbTableName;
196
		destination.setQuery(sql);
197
		destination.update(sql);
198
		
199
		return true;
200
	}
201
	
202
	/**
203
	 * Returns the <code>IMIS_Id</code> attribute.
204
	 * @param reference The {@link Reference Reference}.
205
	 * @return The <code>IMIS_Id</code> attribute.
206
	 * @see MethodMapper
207
	 */
208
	@SuppressWarnings("unused")
209
	private static Integer getIMIS_Id(Reference<?> reference) {
210
		return null;
211
	}
212
	
213
	/**
214
	 * Returns the <code>SourceCategoryFK</code> attribute.
215
	 * @param reference The {@link Reference Reference}.
216
	 * @return The <code>SourceCategoryFK</code> attribute.
217
	 * @see MethodMapper
218
	 */
219
	@SuppressWarnings("unused")
220
	private static Integer getSourceCategoryFK(Reference<?> reference) {
221
		Integer result = null;
222
		try {
223
		result = PesiTransformer.reference2SourceCategoryFK(reference);
224
		} catch (Exception e) {
225
			e.printStackTrace();
226
		}
227
		return result;
228
	}
229
	
230
	/**
231
	 * Returns the <code>SourceCategoryCache</code> attribute.
232
	 * @param reference The {@link Reference Reference}.
233
	 * @return The <code>SourceCategoryCache</code> attribute.
234
	 * @see MethodMapper
235
	 */
236
	@SuppressWarnings("unused")
237
	private static String getSourceCategoryCache(Reference<?> reference) {
238
		String result = null;
239
		try {
240
		result = PesiTransformer.getSourceCategoryCache(reference);
241
		} catch (Exception e) {
242
			e.printStackTrace();
243
		}
244
		return result;
245
	}
246

    
247
	/**
248
	 * Returns the <code>Name</code> attribute. The corresponding CDM attribute is <code>title</code>.
249
	 * @param reference The {@link Reference Reference}.
250
	 * @return The <code>Name</code> attribute.
251
	 * @see MethodMapper
252
	 */
253
	@SuppressWarnings("unused")
254
	private static String getName(Reference<?> reference) {
255
		if (reference != null) {
256
			return reference.getTitleCache(); // was getTitle()
257
		} else {
258
			return null;
259
		}
260
	}
261
	
262
	/**
263
	 * Returns the <code>AuthorString</code> attribute. The corresponding CDM attribute is the <code>titleCache</code> of an <code>authorTeam</code>.
264
	 * @param reference The {@link Reference Reference}.
265
	 * @return The <code>AuthorString</code> attribute.
266
	 * @see MethodMapper
267
	 */
268
	@SuppressWarnings("unused")
269
	private static String getAuthorString(Reference<?> reference) {
270
		String result = null;
271

    
272
		try {
273
		if (reference != null) {
274
			TeamOrPersonBase team = reference.getAuthorTeam();
275
			if (team != null) {
276
				result = team.getTitleCache();
277
//				result = team.getNomenclaturalTitle();
278
			} else {
279
				result = null;
280
			}
281
		}
282
		} catch (Exception e) {
283
			e.printStackTrace();
284
		}
285
		
286
		return result;
287
	}
288

    
289
	/**
290
	 * Returns the <code>NomRefCache</code> attribute. The corresponding CDM attribute is <code>titleCache</code>.
291
	 * @param reference The {@link Reference Reference}.
292
	 * @return The <code>NomRefCache</code> attribute.
293
	 * @see MethodMapper
294
	 */
295
	@SuppressWarnings("unused")
296
	private static String getNomRefCache(Reference<?> reference) {
297
		return null;
298
//		if (reference != null) {
299
//			return reference.getTitleCache();
300
//		} else {
301
//			return null;
302
//		}
303
	}
304

    
305
	/**
306
	 * Returns the <code>Notes</code> attribute.
307
	 * @param reference The {@link Reference Reference}.
308
	 * @return The <code>Notes</code> attribute.
309
	 * @see MethodMapper
310
	 */
311
	@SuppressWarnings("unused")
312
	private static String getNotes(Reference<?> reference) {
313
		// TODO
314
		return null;
315
	}
316

    
317
	/**
318
	 * Returns the <code>RefIdInSource</code> attribute.
319
	 * @param reference The {@link Reference Reference}.
320
	 * @return The <code>RefIdInSource</code> attribute.
321
	 * @see MethodMapper
322
	 */
323
	@SuppressWarnings("unused")
324
	private static String getRefIdInSource(Reference<?> reference) {
325
		String result = null;
326

    
327
		try {
328
		if (reference != null) {
329
			Set<IdentifiableSource> sourceAll = reference.getSources();
330
			Set<IdentifiableSource> sourceCandidates = filterOriginalPesiDbSources(sourceAll);
331
			
332
			if (sourceCandidates.size() == 1) {
333
				result = sourceCandidates.iterator().next().getIdInSource();
334
			} else if (sourceCandidates.size() > 1) {
335
				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() + ")");
336
				int count = 1;
337
//				for (IdentifiableSource source : sources) {
338
//					result += source.getIdInSource();
339
//					if (count < sources.size()) {
340
//						result += "; ";
341
//					}
342
//					count++;
343
//				}
344
			}
345
		}
346
		} catch (Exception e) {
347
			e.printStackTrace();
348
		}
349

    
350
		return result;
351
	}
352

    
353
	private static Set<IdentifiableSource> filterOriginalPesiDbSources(
354
			Set<IdentifiableSource> sourceAll) {
355
		Set<IdentifiableSource> sourceCandidates = new HashSet<IdentifiableSource>();
356
		for (IdentifiableSource source : sourceAll){
357
			if (isOriginalPesiDbSource(source)){
358
				sourceCandidates.add(source);
359
			}
360
		}
361
		return sourceCandidates;
362
	}
363

    
364
	private static boolean isOriginalPesiDbSource(IdentifiableSource source) {
365
		return (source.getCitation() != null) &&
366
				source.getCitation().getType().equals(ReferenceType.Database);
367
	}
368

    
369
	/**
370
	 * Returns the <code>OriginalDB</code> attribute. The corresponding CDM attribute is the <code>titleCache</code> of a <code>citation</code>.
371
	 * @param reference The {@link Reference Reference}.
372
	 * @return The <code>OriginalDB</code> attribute.
373
	 * @see MethodMapper
374
	 */
375
	@SuppressWarnings("unused")
376
	private static String getOriginalDB(Reference<?> reference) {
377
		String result = "";
378

    
379
		try {
380
		if (reference != null) {
381
			Set<IdentifiableSource> sourcesAll = reference.getSources();
382
			Set<IdentifiableSource> sourceCandidates = filterOriginalPesiDbSources(sourcesAll); 
383
			
384
			if (sourceCandidates.size() == 1) {
385
				Reference citation = sourceCandidates.iterator().next().getCitation();
386
				if (citation != null) {
387
					result = PesiTransformer.databaseString2Abbreviation(citation.getTitleCache()); //or just title
388
				} else {
389
					logger.warn("OriginalDB can not be determined because the citation of this source is NULL: " + sourceCandidates.iterator().next().getUuid());
390
				}
391
			} else if (sourceCandidates.size() > 1) {
392
				logger.warn("Taxon has multiple IdentifiableSources: " + reference.getUuid() + " (" + reference.getTitleCache() + ")");
393
				int count = 1;
394
				for (IdentifiableSource source : sourceCandidates) {
395
					Reference citation = source.getCitation();
396
					if (citation != null) {
397
						result += PesiTransformer.databaseString2Abbreviation(citation.getTitleCache());
398
						if (count < sourceCandidates.size()) {
399
							result += "; ";
400
						}
401
						count++;
402
					}
403
				}
404
			} else {
405
				result = null;
406
			}
407
		}
408
		} catch (Exception e) {
409
			e.printStackTrace();
410
		}
411

    
412
		return result;
413
	}
414

    
415
	/* (non-Javadoc)
416
	 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#isIgnore(eu.etaxonomy.cdm.io.common.IoStateBase)
417
	 */
418
	@Override
419
	protected boolean isIgnore(PesiExportState state) {
420
		return ! state.getConfig().getDoReferences().equals(DO_REFERENCES.ALL);
421
	}
422

    
423
	/**
424
	 * Returns the CDM to PESI specific export mappings.
425
	 * @return The {@link PesiExportMapping PesiExportMapping}.
426
	 */
427
	private PesiExportMapping getMapping() {
428
		PesiExportMapping mapping = new PesiExportMapping(dbTableName);
429
		ExtensionType extensionType = null;
430
		
431
		mapping.addMapper(IdMapper.NewInstance("SourceId"));
432
		
433
		// IMIS_Id
434
		extensionType = (ExtensionType)getTermService().find(ErmsTransformer.IMIS_UUID);
435
		if (extensionType != null) {
436
			mapping.addMapper(DbExtensionMapper.NewInstance(extensionType, "IMIS_Id"));
437
		} else {
438
			mapping.addMapper(MethodMapper.NewInstance("IMIS_Id", this));
439
		}
440
		
441
		mapping.addMapper(MethodMapper.NewInstance("SourceCategoryFK", this));
442
		mapping.addMapper(MethodMapper.NewInstance("SourceCategoryCache", this));
443
		mapping.addMapper(MethodMapper.NewInstance("Name", this));
444
		mapping.addMapper(DbStringMapper.NewInstance("referenceAbstract", "Abstract"));
445
		mapping.addMapper(DbStringMapper.NewInstance("title", "Title"));
446
		mapping.addMapper(MethodMapper.NewInstance("AuthorString", this));
447
		mapping.addMapper(DbTimePeriodMapper.NewInstance("datePublished", "RefYear"));
448
		mapping.addMapper(MethodMapper.NewInstance("NomRefCache", this));
449
		mapping.addMapper(DbUriMapper.NewInstance("uri", "Link"));
450
		mapping.addMapper(MethodMapper.NewInstance("Notes", this));
451
		mapping.addMapper(MethodMapper.NewInstance("RefIdInSource", this));
452
		mapping.addMapper(MethodMapper.NewInstance("OriginalDB", this));
453

    
454
		return mapping;
455
	}
456

    
457
}
(15-15/17)