Project

General

Profile

Download (15.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.EnumSet;
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.DbAnnotationMapper;
24
import eu.etaxonomy.cdm.io.common.mapping.out.DbDoiMapper;
25
import eu.etaxonomy.cdm.io.common.mapping.out.DbExtensionMapper;
26
import eu.etaxonomy.cdm.io.common.mapping.out.DbStringMapper;
27
import eu.etaxonomy.cdm.io.common.mapping.out.DbTimePeriodMapper;
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.Extension;
34
import eu.etaxonomy.cdm.model.common.ExtensionType;
35
import eu.etaxonomy.cdm.model.common.IdentifiableSource;
36
import eu.etaxonomy.cdm.model.reference.Reference;
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
 *
42
 * @author e.-m.lee
43
 * @since 11.02.2010
44
 */
45
@Component
46
public class PesiSourceExport extends PesiExportBase {
47

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

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

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

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

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

    
67
	/**
68
	 * Checks whether a sourceId was stored already.
69
	 * @param sourceId
70
	 * @return
71
	 */
72
	protected boolean isStoredSourceId(Integer sourceId) {
73
		if (storedSourceIds.contains(sourceId)) {
74
			return true;
75
		} else {
76
			return false;
77
		}
78
	}
79

    
80
	/**
81
	 * Adds a sourceId to the list of storedSourceIds.
82
	 * @param sourceId
83
	 */
84
	protected void addToStoredSourceIds(Integer sourceId) {
85
		if (! storedSourceIds.contains(sourceId)) {
86
			this.storedSourceIds.add(sourceId);
87
		}
88
	}
89

    
90
	@Override
91
	protected void doInvoke(PesiExportState state) {
92
		try{
93
			logger.info("*** Started Making " + pluralString + " ...");
94

    
95
			// Get the limit for objects to save within a single transaction.
96
			int limit = modCount;//pesiExportConfigurator.getLimitSave();
97

    
98
			// Stores whether this invoke was successful or not.
99
			boolean success = true ;
100

    
101
			// PESI: Clear the database table Source.
102
			//doDelete(state);  -> done by stored procedure
103

    
104
			// Get specific mappings: (CDM) Reference -> (PESI) Source
105
			PesiExportMapping mapping = getMapping();
106

    
107
			// Initialize the db mapper
108
			mapping.initialize(state);
109

    
110
			// Create the Sources
111
			int count = 0;
112
			int pastCount = 0;
113
			TransactionStatus txStatus = null;
114
			List<Reference> list = null;
115

    
116
//			logger.warn("PHASE 1...");
117
			// Start transaction
118
			txStatus = startTransaction(true);
119
			logger.info("Started new transaction. Fetching some " + pluralString + " (max: " + limit + ") ...");
120
			while ((list = getReferenceService().list(null, limit, count, null, null)).size() > 0) {
121

    
122
				logger.debug("Fetched " + list.size() + " " + pluralString + ". Exporting...");
123
				for (Reference reference : list) {
124
					doCount(count++, modCount, pluralString);
125
					success &= mapping.invoke(reference);
126
				}
127

    
128
				// Commit transaction
129
				commitTransaction(txStatus);
130
				logger.debug("Committed transaction.");
131
				logger.info("Exported " + (count - pastCount) + " " + pluralString + ". Total: " + count);
132
				pastCount = count;
133

    
134
				// Start transaction
135
				txStatus = startTransaction(true);
136
				if (logger.isDebugEnabled()) {
137
                    logger.debug("Started new transaction. Fetching some " + pluralString + " (max: " + limit + ") ...");
138
                }
139
			}
140
			if (list.size() == 0) {
141
				logger.info("No " + pluralString + " left to fetch.");
142
			}
143
			// Commit transaction
144
			commitTransaction(txStatus);
145
			logger.info("Committed transaction.");
146

    
147
			logger.info("*** Finished Making " + pluralString + " ..." + getSuccessString(success));
148

    
149
			if (!success){
150
				state.getResult().addError("An error occurred in PesiSourceExport.invoke");
151
			}
152
			return;
153
		} catch (SQLException e) {
154
			e.printStackTrace();
155
			logger.error(e.getMessage());
156
			state.getResult().addException(e);
157
			return;
158
		}
159
	}
160

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

    
170
		// Clear Sources
171
		String sql = "DELETE FROM " + dbTableName;
172
		destination.setQuery(sql);
173
		destination.update(sql);
174

    
175
		return true;
176
	}
177

    
178
	/**
179
	 * Returns the <code>IMIS_Id</code> attribute.
180
	 * @param reference The {@link Reference Reference}.
181
	 * @return The <code>IMIS_Id</code> attribute.
182
	 * @see MethodMapper
183
	 */
184
	@SuppressWarnings("unused")
185
	private static Integer getIMIS_Id(Reference reference) {
186
		return null;
187
	}
188

    
189
	/**
190
	 * Returns the <code>SourceCategoryFK</code> attribute.
191
	 * @param reference The {@link Reference Reference}.
192
	 * @return The <code>SourceCategoryFK</code> attribute.
193
	 * @see MethodMapper
194
	 */
195
	@SuppressWarnings("unused")
196
	private static Integer getSourceCategoryFK(Reference reference) {
197
		Integer result = null;
198
		try {
199
		    result = PesiTransformer.reference2SourceCategoryFK(reference);
200
		} catch (Exception e) {
201
			e.printStackTrace();
202
		}
203
		return result;
204
	}
205

    
206
	/**
207
	 * Returns the <code>SourceCategoryCache</code> attribute.
208
	 * @param reference The {@link Reference Reference}.
209
	 * @return The <code>SourceCategoryCache</code> attribute.
210
	 * @see MethodMapper
211
	 */
212
	@SuppressWarnings("unused")
213
	private static String getSourceCategoryCache(Reference reference, PesiExportState state) {
214
		return state.getTransformer().getCacheByReference(reference);
215
	}
216

    
217
	/**
218
	 * Returns the <code>Name</code> attribute. The corresponding CDM attribute is <code>title</code>.
219
	 * @param reference The {@link Reference Reference}.
220
	 * @return The <code>Name</code> attribute.
221
	 * @see MethodMapper
222
	 */
223
	@SuppressWarnings("unused")
224
	private static String getName(Reference reference) {
225
		if (reference != null) {
226
		    String titleCache = reference.getTitleCache();
227
		    //handling copied from DbObjectMapper
228
		    if (titleCache == null || titleCache.length()>250 || titleCache.endsWith("...")){
229
                Set<String> fullCache = reference.getExtensions(ExtensionType.uuidExtNonTruncatedCache);
230
                if (!fullCache.isEmpty()){
231
                    if (fullCache.size()>1){
232
                        logger.warn("Reference has more than 1 'Non truncated cache' extensions. This should not happen. Arbitrary one taken.");
233
                    }
234
                    String value = fullCache.iterator().next();
235
                    if(isNotBlank(value)){
236
                        titleCache = value;
237
                    }
238
                }
239
            }
240
		    return titleCache == null ? null : titleCache.trim();
241
		} else {
242
			return null;
243
		}
244
	}
245

    
246

    
247
	/**
248
	 * Returns the <code>AuthorString</code> attribute. The corresponding CDM attribute is the <code>titleCache</code> of an <code>authorTeam</code>.
249
	 * @param reference The {@link Reference Reference}.
250
	 * @return The <code>AuthorString</code> attribute.
251
	 * @see MethodMapper
252
	 */
253
	@SuppressWarnings("unused")
254
	private static String getAuthorString(Reference reference) {
255
		String result = null;
256
		Set<Extension> extensions;
257
		try {
258
    		if (reference != null) {
259
    			TeamOrPersonBase<?> team = reference.getAuthorship();
260
    			if (team != null) {
261
    				result = team.getTitleCache();
262
    			}else if (!reference.getExtensions(ErmsTransformer.uuidExtAuthor).isEmpty()){
263
    			    result = reference.getExtensions(ErmsTransformer.uuidExtAuthor).iterator().next();
264
    			}
265
    		}
266
		} catch (Exception e) {
267
			e.printStackTrace();
268
		}
269

    
270
		return result;
271
	}
272

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

    
289
	/**
290
	 * Returns the <code>RefIdInSource</code> attribute.
291
	 * @param reference The {@link Reference Reference}.
292
	 * @return The <code>RefIdInSource</code> attribute.
293
	 * @see MethodMapper
294
	 */
295
	@SuppressWarnings("unused")
296
	private static String getRefIdInSource(Reference reference) {
297
		String result = null;
298

    
299
		try {
300
    		if (reference != null) {
301
    			Set<IdentifiableSource> sourceAll = reference.getSources();
302
    			Set<IdentifiableSource> sourceCandidates = filterPesiSources(sourceAll);
303

    
304
    			if (sourceCandidates.size() == 1) {
305
    				result = sourceCandidates.iterator().next().getIdInSource();
306
    			} else if (sourceCandidates.size() > 1) {
307
    				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() + ")");
308
    				int count = 1;
309
    //				for (IdentifiableSource source : sources) {
310
    //					result += source.getIdInSource();
311
    //					if (count < sources.size()) {
312
    //						result += "; ";
313
    //					}
314
    //					count++;
315
    //				}
316
    			}
317
    		}
318
		} catch (Exception e) {
319
			e.printStackTrace();
320
		}
321

    
322
		return result;
323
	}
324

    
325
//	private static Set<IdentifiableSource> filterOriginalPesiDbSources(
326
//			Set<IdentifiableSource> sourceAll) {
327
//		Set<IdentifiableSource> sourceCandidates = new HashSet<>();
328
//		for (IdentifiableSource source : sourceAll){
329
//			if (isOriginalPesiDbSource(source)){
330
//				sourceCandidates.add(source);
331
//			}
332
//		}
333
//		return sourceCandidates;
334
//	}
335
//
336
//	private static boolean isOriginalPesiDbSource(IdentifiableSource source) {
337
//		return (source.getCitation() != null) &&
338
//				source.getCitation().getType().equals(ReferenceType.Database);
339
//	}
340

    
341
	/**
342
	 * Returns the <code>OriginalDB</code> attribute.
343
	 * @param reference The {@link Reference Reference}.
344
	 * @return The <code>OriginalDB</code> attribute.
345
	 * @see MethodMapper
346
	 */
347
	@SuppressWarnings("unused")
348
	private static String getOriginalDB(Reference reference) {
349
	    //TODO may not work for E+M and FauEu as they may not have import sources for all data
350
	    EnumSet<PesiSource> sources  = getSources(reference);
351
	    return PesiTransformer.getOriginalDbBySources(sources);
352

    
353
//	    String result = "";
354
//
355
//		try {
356
//    		if (reference != null) {
357
//    			Set<IdentifiableSource> sourcesAll = reference.getSources();
358
//    			Set<IdentifiableSource> sourceCandidates = filterOriginalPesiDbSources(sourcesAll);
359
//
360
//    			if (sourceCandidates.size() == 1) {
361
//    				Reference citation = sourceCandidates.iterator().next().getCitation();
362
//    				if (citation != null) {
363
//    					result = PesiTransformer.databaseString2Abbreviation(citation.getTitleCache()); //or just title
364
//    				} else {
365
//    					logger.warn("OriginalDB can not be determined because the citation of this source is NULL: " + sourceCandidates.iterator().next().getUuid());
366
//    				}
367
//    			} else if (sourceCandidates.size() > 1) {
368
//    				logger.warn("Taxon has multiple IdentifiableSources: " + reference.getUuid() + " (" + reference.getTitleCache() + ")");
369
//    				int count = 1;
370
//    				for (IdentifiableSource source : sourceCandidates) {
371
//    					Reference citation = source.getCitation();
372
//    					if (citation != null) {
373
//    						result += PesiTransformer.databaseString2Abbreviation(citation.getTitleCache());
374
//    						if (count < sourceCandidates.size()) {
375
//    							result += "; ";
376
//    						}
377
//    						count++;
378
//    					}
379
//    				}
380
//    			} else {
381
//    				result = null;
382
//    			}
383
//    		}
384
//		} catch (Exception e) {
385
//			e.printStackTrace();
386
//		}
387
//
388
//		return result;
389
	}
390

    
391
    @Override
392
    protected boolean doCheck(PesiExportState state) {
393
        return true;
394
    }
395

    
396
	@Override
397
	protected boolean isIgnore(PesiExportState state) {
398
		return ! state.getConfig().getDoReferences().equals(DO_REFERENCES.ALL);
399
	}
400

    
401
	/**
402
	 * Returns the CDM to PESI specific export mappings.
403
	 * @return The {@link PesiExportMapping PesiExportMapping}.
404
	 */
405
	private PesiExportMapping getMapping() {
406
		PesiExportMapping mapping = new PesiExportMapping(dbTableName);
407

    
408
		mapping.addMapper(IdMapper.NewInstance("SourceId"));
409

    
410
		// IMIS_Id
411
		ExtensionType imisExtensionType = (ExtensionType)getTermService().find(ErmsTransformer.uuidExtImis);
412
		if (imisExtensionType != null) {
413
			mapping.addMapper(DbExtensionMapper.NewInstance(imisExtensionType, "IMIS_Id"));
414
		} else {
415
			mapping.addMapper(MethodMapper.NewInstance("IMIS_Id", this));
416
		}
417

    
418
		mapping.addMapper(MethodMapper.NewInstance("SourceCategoryFK", this));
419
		mapping.addMapper(MethodMapper.NewInstance("SourceCategoryCache", this, Reference.class, PesiExportState.class));
420
		mapping.addMapper(MethodMapper.NewInstance("Name", this));
421
		mapping.addMapper(DbStringMapper.NewInstance("referenceAbstract", "Abstract"));
422
		mapping.addMapper(DbStringMapper.NewInstance("title", "Title"));
423
		mapping.addMapper(MethodMapper.NewInstance("AuthorString", this));
424
		mapping.addMapper(DbTimePeriodMapper.NewInstance("datePublished", "RefYear"));
425
		mapping.addMapper(DbDoiMapper.NewInstance("doi", "Doi"));
426

    
427
		mapping.addMapper(MethodMapper.NewInstance("NomRefCache", this));
428
		logger.warn("URI mapping needs to be combined");
429
//		mapping.addMapper(DbUriMapper.NewInstance("uri", "Link"));
430
		mapping.addMapper(DbExtensionMapper.NewInstance(ExtensionType.URL(), "Link"));
431
		mapping.addMapper(DbAnnotationMapper.NewInstance((String)null, "Notes"));
432
		mapping.addMapper(MethodMapper.NewInstance("RefIdInSource", this));
433
		mapping.addMapper(MethodMapper.NewInstance("OriginalDB", this));
434

    
435
		return mapping;
436
	}
437
}
(12-12/14)