Project

General

Profile

Download (16.6 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2007 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

    
10
package eu.etaxonomy.cdm.io.erms;
11

    
12
import java.sql.ResultSet;
13
import java.sql.SQLException;
14
import java.util.HashMap;
15
import java.util.HashSet;
16
import java.util.Map;
17
import java.util.Set;
18
import java.util.UUID;
19

    
20
import org.apache.log4j.Logger;
21
import org.springframework.stereotype.Component;
22

    
23
import eu.etaxonomy.cdm.common.CdmUtils;
24
import eu.etaxonomy.cdm.io.common.IOValidator;
25
import eu.etaxonomy.cdm.io.common.mapping.DbIgnoreMapper;
26
import eu.etaxonomy.cdm.io.common.mapping.DbImportExtensionMapper;
27
import eu.etaxonomy.cdm.io.common.mapping.DbImportMapping;
28
import eu.etaxonomy.cdm.io.common.mapping.DbImportObjectCreationMapper;
29
import eu.etaxonomy.cdm.io.common.mapping.DbImportStringMapper;
30
import eu.etaxonomy.cdm.io.common.mapping.DbNotYetImplementedMapper;
31
import eu.etaxonomy.cdm.io.common.mapping.IMappingImport;
32
import eu.etaxonomy.cdm.io.erms.validation.ErmsTaxonImportValidator;
33
import eu.etaxonomy.cdm.model.common.CdmBase;
34
import eu.etaxonomy.cdm.model.common.ExtensionType;
35
import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
36
import eu.etaxonomy.cdm.model.name.NonViralName;
37
import eu.etaxonomy.cdm.model.name.Rank;
38
import eu.etaxonomy.cdm.model.reference.ReferenceBase;
39
import eu.etaxonomy.cdm.model.taxon.Synonym;
40
import eu.etaxonomy.cdm.model.taxon.Taxon;
41
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
42

    
43

    
44
/**
45
 * @author a.mueller
46
 * @created 20.02.2010
47
 * @version 1.0
48
 */
49
@Component
50
public class ErmsTaxonImport  extends ErmsImportBase<TaxonBase> implements IMappingImport<TaxonBase, ErmsImportState>{
51
	private static final Logger logger = Logger.getLogger(ErmsTaxonImport.class);
52
	
53
	public static final UUID TNS_EXT_UUID = UUID.fromString("41cb0450-ac84-4d73-905e-9c7773c23b05");
54
	
55
	private DbImportMapping mapping;
56
	
57
	//second path is not used anymore, there is now an ErmsTaxonRelationImport class instead
58
	private boolean isSecondPath = false;
59
	
60
	private int modCount = 10000;
61
	private static final String pluralString = "taxa";
62
	private static final String dbTableName = "tu";
63
	private static final Class cdmTargetClass = TaxonBase.class;
64

    
65
	public ErmsTaxonImport(){
66
		super(pluralString, dbTableName, cdmTargetClass);
67
	}
68
	
69
	
70

    
71
//	/* (non-Javadoc)
72
//	 * @see eu.etaxonomy.cdm.io.erms.ErmsImportBase#getIdQuery()
73
//	 */
74
//	@Override
75
//	protected String getIdQuery() {
76
//		String strQuery = " SELECT id FROM tu WHERE id < 300000 " ;
77
//		return strQuery;
78
//	}
79

    
80

    
81
	/* (non-Javadoc)
82
	 * @see eu.etaxonomy.cdm.io.erms.ErmsImportBase#getMapping()
83
	 */
84
	protected DbImportMapping getMapping() {
85
		if (mapping == null){
86
			mapping = new DbImportMapping();
87
			
88
			mapping.addMapper(DbImportObjectCreationMapper.NewInstance(this, "id", TAXON_NAMESPACE)); //id + tu_status
89
			UUID tsnUuid = ErmsTransformer.uuidTsn;
90
			mapping.addMapper(DbImportExtensionMapper.NewInstance("tsn", tsnUuid, "TSN", "TSN", "TSN"));
91
//			mapping.addMapper(DbImportStringMapper.NewInstance("tu_name", "(NonViralName)name.nameCache"));
92
			
93
			UUID displayNameUuid = ErmsTransformer.uuidDisplayName;
94
			mapping.addMapper(DbImportExtensionMapper.NewInstance("tu_displayname", displayNameUuid, "display name", "display name", "display name"));
95
			UUID fuzzyNameUuid = ErmsTransformer.uuidFuzzyName;
96
			mapping.addMapper(DbImportExtensionMapper.NewInstance("tu_fuzzyname", fuzzyNameUuid, "fuzzy name", "fuzzy name", "fuzzy name"));
97
			mapping.addMapper(DbImportStringMapper.NewInstance("tu_authority", "(NonViralName)name.authorshipCache"));
98
			
99
			UUID fossilStatusUuid = ErmsTransformer.uuidFossilStatus;
100
			mapping.addMapper(DbImportExtensionMapper.NewInstance("fossil_name", fossilStatusUuid, "fossil status", "fossil status", "fos. stat."));
101
//			mapping.addMapper(DbImportExtensionTypeCreationMapper.NewInstance("fossil_name", EXTENSION_TYPE_NAMESPACE, "fossil_name", "fossil_name", "fossil_name"));
102
			
103
			UUID credibilityUuid = ErmsTransformer.uuidCredibility;
104
			mapping.addMapper(DbImportExtensionMapper.NewInstance("tu_credibility", credibilityUuid, "credibility", "credibility", "credibility")); //Werte: null, unknown, marked for deletion
105
			
106
			UUID completenessUuid = ErmsTransformer.uuidCompleteness;
107
			mapping.addMapper(DbImportExtensionMapper.NewInstance("tu_completeness", completenessUuid, "completeness", "completeness", "completeness")); //null, unknown, tmpflag, tmp2, tmp3, complete
108
			
109
			UUID unacceptUuid = ErmsTransformer.uuidUnacceptReason;
110
			mapping.addMapper(DbImportExtensionMapper.NewInstance("tu_unacceptreason", unacceptUuid, "unaccept reason", "unaccept reason", "reason"));
111
			
112
			UUID qualityUuid = ErmsTransformer.uuidQualityStatus;
113
			mapping.addMapper(DbImportExtensionMapper.NewInstance("qualitystatus_name", qualityUuid, "quality status", "quality status", "quality status")); //checked by Tax Editor ERMS1.1, Added by db management team (2x), checked by Tax Editor
114
			
115
//			UUID hiddenUuid = ErmsTransformer.uuidHidden;
116
//			mapping.addMapper(DbImportMarkerCreationMapper.Mapper.NewInstance("qualitystatus_name", qualityUuid, "quality status", "quality status", "quality status")); //checked by Tax Editor ERMS1.1, Added by db management team (2x), checked by Tax Editor
117
			
118
			
119
			//ignore
120
			mapping.addMapper(DbIgnoreMapper.NewInstance("tu_marine", "marine flag not implemented in PESI"));
121
			mapping.addMapper(DbIgnoreMapper.NewInstance("tu_brackish", "brackish flag not implemented in PESI"));
122
			mapping.addMapper(DbIgnoreMapper.NewInstance("tu_fresh", "freshwater flag not implemented in PESI"));
123
			mapping.addMapper(DbIgnoreMapper.NewInstance("tu_terrestrial", "terrestrial flag not implemented in PESI"));
124
			mapping.addMapper(DbIgnoreMapper.NewInstance("tu_fossil", "tu_fossil implemented as foreign key"));
125
			mapping.addMapper(DbIgnoreMapper.NewInstance("cache_citation", "citation cache not needed in PESI"));
126
			mapping.addMapper(DbNotYetImplementedMapper.NewInstance("tu_sp", "included in rank/object creation")); 
127
			
128
			
129
			//not yet implemented or ignore
130
			mapping.addMapper(DbNotYetImplementedMapper.NewInstance("tu_hidden", "Needs DbImportMarkerMapper implemented"));
131
			
132
//			//second path / implemented in ErmsTaxonRelationImport
133
//			DbImportMapping secondPathMapping = new DbImportMapping();
134
//			secondPathMapping.addMapper(DbImportTaxIncludedInMapper.NewInstance("id", "tu_parent", TAXON_NAMESPACE, null)); //there is only one tree
135
//			secondPathMapping.addMapper(DbImportSynonymMapper.NewInstance("id", "tu_acctaxon", TAXON_NAMESPACE, null)); 			
136
//			secondPathMapping.addMapper(DbImportNameTypeDesignationMapper.NewInstance("id", "tu_typetaxon", NAME_NAMESPACE, "tu_typedesignationstatus"));
137
//			secondPathMapping.addMapper(DbNotYetImplementedMapper.NewInstance("tu_acctaxon"));
138
//			mapping.setSecondPathMapping(secondPathMapping);
139
			
140
		}
141
		return mapping;
142
	}
143

    
144
	/* (non-Javadoc)
145
	 * @see eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportBase#getRecordQuery(eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportConfigurator)
146
	 */
147
	@Override
148
	protected String getRecordQuery(ErmsImportConfigurator config) {
149
		String strSelect = " SELECT tu.*, parent1.tu_name AS parent1name, parent2.tu_name AS parent2name, parent3.tu_name AS parent3name, " 
150
			+ " parent1.tu_rank AS parent1rank, parent2.tu_rank AS parent2rank, parent3.tu_rank AS parent3rank, " + 
151
			" status.status_id as status_id,  fossil.fossil_name, qualitystatus.qualitystatus_name";
152
		String strFrom = " FROM tu  LEFT OUTER JOIN  tu AS parent1 ON parent1.id = tu.tu_parent " + 
153
				" LEFT OUTER JOIN   tu AS parent2  ON parent2.id = parent1.tu_parent " + 
154
				" LEFT OUTER JOIN tu AS parent3 ON parent2.tu_parent = parent3.id " + 
155
				" LEFT OUTER JOIN status ON tu.tu_status = status.status_id " + 
156
				" LEFT OUTER JOIN fossil ON tu.tu_fossil = fossil.fossil_id " +
157
				" LEFT OUTER JOIN qualitystatus ON tu.tu_qualitystatus = qualitystatus.id ";
158
		String strWhere = " WHERE ( tu.id IN (" + ID_LIST_TOKEN + ") )";
159
		String strRecordQuery = strSelect + strFrom + strWhere;
160
		return strRecordQuery;
161
	}
162
	
163

    
164
//	/**
165
//	 * @param config
166
//	 * @return
167
//	 */
168
//	private String getSecondPathRecordQuery(ErmsImportConfigurator config) {
169
//		//TODO get automatic by second path mappers
170
//		String selectAttributes = "id, tu_parent, tu_typetaxon, tu_typetaxon, tu_typedesignation, tu_acctaxon, tu_status"; 
171
//		String strRecordQuery = 
172
//			" SELECT  " + selectAttributes + 
173
//			" FROM tu " +
174
//			" WHERE ( tu.id IN (" + ID_LIST_TOKEN + ") )";
175
//		return strRecordQuery;
176
//	}
177

    
178

    
179
//	private String getSecondPathIdQuery(){
180
//		return getIdQuery();
181
//	}
182
	
183
	/* (non-Javadoc)
184
	 * @see eu.etaxonomy.cdm.io.erms.ErmsImportBase#doInvoke(eu.etaxonomy.cdm.io.erms.ErmsImportState)
185
	 */
186
	@Override
187
	protected boolean doInvoke(ErmsImportState state) {
188
		//first path
189
		boolean success = super.doInvoke(state);
190
		
191
//		//second path
192
//		isSecondPath = true;
193
//		ErmsImportConfigurator config = state.getConfig();
194
//		Source source = config.getSource();
195
//			
196
//		String strIdQuery = getSecondPathIdQuery();
197
//		String strRecordQuery = getSecondPathRecordQuery(config);
198
//
199
//		int recordsPerTransaction = config.getRecordsPerTransaction();
200
//		try{
201
//			ResultSetPartitioner partitioner = ResultSetPartitioner.NewInstance(source, strIdQuery, strRecordQuery, recordsPerTransaction);
202
//			while (partitioner.nextPartition()){
203
//				partitioner.doPartition(this, state);
204
//			}
205
//		} catch (SQLException e) {
206
//			logger.error("SQLException:" +  e);
207
//			return false;
208
//		}
209
//		
210
//		isSecondPath = false;
211
//
212
//		logger.info("end make " + getPluralString() + " ... " + getSuccessString(success));
213
		return success;
214

    
215
	}
216

    
217

    
218

    
219
	/* (non-Javadoc)
220
	 * @see eu.etaxonomy.cdm.io.berlinModel.in.IPartitionedIO#getRelatedObjectsForPartition(java.sql.ResultSet)
221
	 */
222
	public Map<Object, Map<String, ? extends CdmBase>> getRelatedObjectsForPartition(ResultSet rs) {
223
		String nameSpace;
224
		Class cdmClass;
225
		Set<String> idSet;
226
		Map<Object, Map<String, ? extends CdmBase>> result = new HashMap<Object, Map<String, ? extends CdmBase>>();
227
		
228
		try{
229
				Set<String> nameIdSet = new HashSet<String>();
230
				Set<String> referenceIdSet = new HashSet<String>();
231
				while (rs.next()){
232
	//				handleForeignKey(rs, nameIdSet, "PTNameFk");
233
	//				handleForeignKey(rs, referenceIdSet, "PTRefFk");
234
				}
235

    
236
			//reference map
237
//			nameSpace = "Reference";
238
//			cdmClass = ReferenceBase.class;
239
//			Map<String, Person> referenceMap = (Map<String, Person>)getCommonService().getSourcedObjectsByIdInSource(Person.class, teamIdSet, nameSpace);
240
//			result.put(ReferenceBase.class, referenceMap);
241

    
242
		} catch (SQLException e) {
243
			throw new RuntimeException(e);
244
		}
245
		return result;
246
	}
247
	
248

    
249
	/* (non-Javadoc)
250
	 * @see eu.etaxonomy.cdm.io.common.mapping.IMappingImport#createObject(java.sql.ResultSet)
251
	 */
252
	public TaxonBase createObject(ResultSet rs, ErmsImportState state) throws SQLException {
253
		int statusId = rs.getInt("status_id");
254
		String tuName = rs.getString("tu_name");
255
		String displayName = rs.getString("tu_displayname");
256
		
257
		String parent1Name = rs.getString("parent1name");
258
		Integer parent1Rank = rs.getInt("parent1rank");
259
		
260
		String parent2Name = rs.getString("parent2name");
261
		Integer parent2Rank = rs.getInt("parent2rank");
262
		
263
		String parent3Name = rs.getString("parent3name");
264
		Integer parent3Rank = rs.getInt("parent3rank");
265
		
266
		
267
		NonViralName taxonName = getTaxonName(rs, state);
268
		//set epithets
269
		if (taxonName.isGenus() || taxonName.isSupraGeneric()){
270
			taxonName.setGenusOrUninomial(tuName);
271
		}else if (taxonName.isInfraGeneric()){
272
			taxonName.setInfraGenericEpithet(tuName);
273
			taxonName.setGenusOrUninomial(parent1Name);
274
		}else if (taxonName.isSpecies()){
275
			taxonName.setSpecificEpithet(tuName);
276
			getGenusAndInfraGenus(parent1Name, parent2Name, parent1Rank, taxonName);
277
		}else if (taxonName.isInfraSpecific()){
278
			if (parent1Rank < 220){
279
				handleException(parent1Rank, taxonName, displayName);
280
			}
281
			taxonName.setInfraSpecificEpithet(tuName);
282
			taxonName.setSpecificEpithet(parent1Name);
283
			getGenusAndInfraGenus(parent2Name, parent3Name, parent2Rank, taxonName);
284
		}else if (taxonName.getRank()== null){
285
			logger.warn("rank super domain still needs to be implemented. Used domain instead.");
286
			if ("Biota".equalsIgnoreCase(tuName)){
287
				Rank rank = Rank.DOMAIN();  //should be Superdomain
288
				taxonName.setRank(rank);
289
				taxonName.setGenusOrUninomial(tuName);
290
			}else{
291
				String warning = "TaxonName has no rank. Use namecache.";
292
				logger.warn(warning);
293
				taxonName.setNameCache(tuName);
294
			}
295
			
296
		}
297
		//e.g. Leucon [Platyhelminthes] ornatus
298
		if (containsBrackets(displayName)){
299
			taxonName.setNameCache(displayName);
300
			logger.warn("Set name cache: " +  displayName);
301
		}
302
		
303
		//add original source for taxon name (taxon original source is added in mapper
304
		ReferenceBase citation = state.getConfig().getSourceReference();
305
		addOriginalSource(rs, taxonName, "id", NAME_NAMESPACE, citation);
306
		
307
//		taxonName.setNameCache("Test");
308
		
309
		ErmsImportConfigurator config = state.getConfig();
310
		ReferenceBase sec = config.getSourceReference();
311
		if (statusId == 1){
312
			return Taxon.NewInstance(taxonName, sec);
313
		}else{
314
			return Synonym.NewInstance(taxonName, sec);
315
		}
316
	}
317

    
318

    
319

    
320
	/**
321
	 * @param parent1Rank
322
	 * @param displayName 
323
	 * @param taxonName 
324
	 */
325
	private void handleException(Integer parent1Rank, NonViralName taxonName, String displayName) {
326
		logger.warn("Parent of infra specific taxon is higher than species. Used nameCache: " + displayName) ;
327
		taxonName.setNameCache(displayName);
328
	}
329

    
330

    
331

    
332
	/**
333
	 * @param displayName
334
	 * @return
335
	 */
336
	private boolean containsBrackets(String displayName) {
337
		int index = displayName.indexOf("[");
338
		return (index > -1);
339
	}
340

    
341

    
342

    
343
	/**
344
	 * @param parent1Name
345
	 * @param parent2Name
346
	 * @param parent1Rank
347
	 * @param taxonName
348
	 */
349
	private void getGenusAndInfraGenus(String parentName, String grandParentName, Integer parent1Rank, NonViralName taxonName) {
350
		if (parent1Rank <220 && parent1Rank > 180){
351
			//parent is infrageneric
352
			taxonName.setInfraGenericEpithet(parentName);
353
			taxonName.setGenusOrUninomial(grandParentName);
354
		}else{
355
			taxonName.setGenusOrUninomial(parentName);
356
		}
357
	}
358

    
359
	/**
360
	 * @param rs
361
	 * @return
362
	 * @throws SQLException 
363
	 */
364
	private NonViralName getTaxonName(ResultSet rs, ErmsImportState state) throws SQLException {
365
		NonViralName result;
366
		Integer kingdomId = parseKingdomId(rs);
367
		Integer intRank = rs.getInt("tu_rank");
368
		
369
		NomenclaturalCode nc = ErmsTransformer.kingdomId2NomCode(kingdomId);
370
		Rank rank = null;
371
		if (kingdomId != null){
372
			rank = state.getRank(intRank, kingdomId);
373
		}
374
		if (nc != null){
375
			result = (NonViralName)nc.getNewTaxonNameInstance(rank);
376
		}else{
377
			result = NonViralName.NewInstance(rank);
378
		}
379
		
380
		return result;
381
	}
382

    
383
	/**
384
	 * Returns the kingdom id by extracting it from the second character in the <code>tu_sp</code> 
385
	 * attribute. If the attribute can not be parsed to a valid id <code>null</code>
386
	 * is returned. If the attribute is <code>null</code> the id of the record is returned.
387
	 * @param rs
388
	 * @return
389
	 * @throws SQLException
390
	 */
391
	private int parseKingdomId(ResultSet rs) throws SQLException {
392
		Integer result = null;
393
		String treeString = rs.getString("tu_sp");
394
		if (treeString != null){
395
			if (CdmUtils.isNotEmpty(treeString) && treeString.length() > 1){
396
				String strKingdom = treeString.substring(1,2);
397
				
398
				if (! treeString.substring(0, 1).equals("#") && ! treeString.substring(2, 3).equals("#") ){
399
					logger.warn("Tree string " + treeString + " has no recognized format");
400
				}else{
401
					try {
402
						result = Integer.valueOf(strKingdom);
403
					} catch (NumberFormatException e) {
404
						logger.warn("Kingdom string " + strKingdom + "could not be recognized as a valid number");
405
					}
406
				}
407
			}
408
		}else{
409
			Integer tu_id = rs.getInt("id");
410
			result = tu_id;
411
		}
412
		return result;
413
	}
414

    
415
	
416
	/* (non-Javadoc)
417
	 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doCheck(eu.etaxonomy.cdm.io.common.IImportConfigurator)
418
	 */
419
	@Override
420
	protected boolean doCheck(ErmsImportState state){
421
		IOValidator<ErmsImportState> validator = new ErmsTaxonImportValidator();
422
		return validator.validate(state);
423
	}
424
	
425
	
426
	/* (non-Javadoc)
427
	 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#isIgnore(eu.etaxonomy.cdm.io.common.IImportConfigurator)
428
	 */
429
	protected boolean isIgnore(ErmsImportState state){
430
		return ! state.getConfig().isDoTaxa();
431
	}
432

    
433

    
434

    
435
}
(13-13/18)