Project

General

Profile

Download (16.7 KB) Statistics
| Branch: | 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.pesi.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.DbImportLsidMapper;
28
import eu.etaxonomy.cdm.io.common.mapping.DbImportMapping;
29
import eu.etaxonomy.cdm.io.common.mapping.DbImportMarkerMapper;
30
import eu.etaxonomy.cdm.io.common.mapping.DbImportObjectCreationMapper;
31
import eu.etaxonomy.cdm.io.common.mapping.DbImportStringMapper;
32
import eu.etaxonomy.cdm.io.common.mapping.DbNotYetImplementedMapper;
33
import eu.etaxonomy.cdm.io.common.mapping.IMappingImport;
34
import eu.etaxonomy.cdm.io.pesi.erms.validation.ErmsTaxonImportValidator;
35
import eu.etaxonomy.cdm.io.pesi.out.PesiTaxonExport;
36
import eu.etaxonomy.cdm.model.common.CdmBase;
37
import eu.etaxonomy.cdm.model.common.ExtensionType;
38
import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
39
import eu.etaxonomy.cdm.model.name.NonViralName;
40
import eu.etaxonomy.cdm.model.name.Rank;
41
import eu.etaxonomy.cdm.model.name.ZoologicalName;
42
import eu.etaxonomy.cdm.model.reference.Reference;
43
import eu.etaxonomy.cdm.model.taxon.Synonym;
44
import eu.etaxonomy.cdm.model.taxon.Taxon;
45
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
46
import eu.etaxonomy.cdm.strategy.cache.name.NonViralNameDefaultCacheStrategy;
47

    
48

    
49
/**
50
 * @author a.mueller
51
 * @created 20.02.2010
52
 */
53
@Component
54
public class ErmsTaxonImport  extends ErmsImportBase<TaxonBase<?>> implements IMappingImport<TaxonBase<?>, ErmsImportState>{
55
	private static final Logger logger = Logger.getLogger(ErmsTaxonImport.class);
56

    
57
	public static final UUID TNS_EXT_UUID = UUID.fromString("41cb0450-ac84-4d73-905e-9c7773c23b05");
58

    
59
	private DbImportMapping<ErmsImportState, ErmsImportConfigurator> mapping;
60

    
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
	@Override
85
    protected DbImportMapping<ErmsImportState, ErmsImportConfigurator> getMapping() {
86
		if (mapping == null){
87
			mapping = new DbImportMapping<ErmsImportState, ErmsImportConfigurator>();
88

    
89
			mapping.addMapper(DbImportObjectCreationMapper.NewInstance(this, "id", TAXON_NAMESPACE)); //id + tu_status
90
			UUID tsnUuid = ErmsTransformer.uuidTsn;
91
			mapping.addMapper(DbImportLsidMapper.NewInstance("GUID", "lsid"));
92

    
93
			ExtensionType tsnExtType = getExtensionType(tsnUuid, "TSN", "TSN", "TSN");
94
			mapping.addMapper(DbImportExtensionMapper.NewInstance("tsn", tsnExtType));
95
//			mapping.addMapper(DbImportStringMapper.NewInstance("tu_name", "(NonViralName)name.nameCache"));
96

    
97
			ExtensionType displayNameExtType = getExtensionType(ErmsTransformer.uuidDisplayName, "display name", "display name", "display name");
98
			mapping.addMapper(DbImportExtensionMapper.NewInstance("tu_displayname", displayNameExtType));
99
			ExtensionType fuzzyNameExtType = getExtensionType(ErmsTransformer.uuidFuzzyName, "fuzzy name", "fuzzy name", "fuzzy name");
100
			mapping.addMapper(DbImportExtensionMapper.NewInstance("tu_fuzzyname", fuzzyNameExtType));
101
			mapping.addMapper(DbImportStringMapper.NewInstance("tu_authority", "(NonViralName)name.authorshipCache"));
102

    
103
			ExtensionType fossilStatusExtType = getExtensionType(ErmsTransformer.uuidFossilStatus, "fossil status", "fossil status", "fos. stat.");
104
			mapping.addMapper(DbImportExtensionMapper.NewInstance("fossil_name", fossilStatusExtType));
105
//			mapping.addMapper(DbImportExtensionTypeCreationMapper.NewInstance("fossil_name", EXTENSION_TYPE_NAMESPACE, "fossil_name", "fossil_name", "fossil_name"));
106

    
107
			ExtensionType unacceptExtType = getExtensionType(ErmsTransformer.uuidUnacceptReason, "unaccept reason", "unaccept reason", "reason");
108
			mapping.addMapper(DbImportExtensionMapper.NewInstance("tu_unacceptreason", unacceptExtType));
109

    
110
			ExtensionType qualityStatusExtType = getExtensionType(ErmsTransformer.uuidQualityStatus, "quality status", "quality status", "quality status");
111
			mapping.addMapper(DbImportExtensionMapper.NewInstance("qualitystatus_name", qualityStatusExtType)); //checked by Tax Editor ERMS1.1, Added by db management team (2x), checked by Tax Editor
112

    
113
			mapping.addMapper(DbImportMarkerMapper.NewInstance("tu_marine", ErmsTransformer.uuidMarkerMarine, "marine", "marine", "marine", null));
114
			mapping.addMapper(DbImportMarkerMapper.NewInstance("tu_brackish", ErmsTransformer.uuidMarkerBrackish, "brackish", "brackish", "brackish", null));
115
			mapping.addMapper(DbImportMarkerMapper.NewInstance("tu_fresh", ErmsTransformer.uuidMarkerFreshwater, "freshwater", "fresh", "fresh", null));
116
			mapping.addMapper(DbImportMarkerMapper.NewInstance("tu_terrestrial", ErmsTransformer.uuidMarkerTerrestrial, "terrestrial", "terrestrial", "terrestrial", null));
117

    
118

    
119
//			UUID hiddenUuid = ErmsTransformer.uuidHidden;
120
//			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
121

    
122
			//not yet implemented
123
			mapping.addMapper(DbNotYetImplementedMapper.NewInstance("tu_sp", "included in rank/object creation"));
124
			mapping.addMapper(DbIgnoreMapper.NewInstance("cache_citation", "Needs check if this is needed in PESI"));
125

    
126

    
127
			//ignore
128
			mapping.addMapper(DbIgnoreMapper.NewInstance("tu_fossil", "tu_fossil implemented as foreign key"));
129

    
130
		}
131

    
132
		return mapping;
133
	}
134

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

    
154

    
155
	/* (non-Javadoc)
156
	 * @see eu.etaxonomy.cdm.io.erms.ErmsImportBase#doInvoke(eu.etaxonomy.cdm.io.erms.ErmsImportState)
157
	 */
158
	@Override
159
	protected void doInvoke(ErmsImportState state) {
160
		state.setAcceptedTaxaKeys(getAcceptedTaxaKeys(state));
161

    
162
		//first path
163
		super.doInvoke(state);
164
		return;
165

    
166
	}
167

    
168

    
169

    
170
	private Set<Integer> getAcceptedTaxaKeys(ErmsImportState state) {
171
		Set<Integer> result = new HashSet<Integer>();
172
		String parentCol = "tu_parent";
173
		String accCol = " tu_acctaxon";
174
		String idCol = " id ";
175
		String tuFk = "tu_id";
176
		String taxonTable = "tu";
177
		String vernacularsTable = "vernaculars";
178
		String distributionTable = "dr";
179
		String sql = " SELECT DISTINCT %s FROM %s  " +
180
				" UNION  SELECT %s FROM %s WHERE %s is NULL" +
181
				" UNION  SELECT DISTINCT %s FROM %s " +
182
				" UNION  SELECT DISTINCT %s FROM %s " +
183
				" UNION  SELECT DISTINCT %s FROM %s ";
184
		sql = String.format(sql,
185
				parentCol, taxonTable,
186
				idCol, taxonTable, accCol,
187
				accCol, taxonTable,
188
				tuFk, vernacularsTable,
189
				tuFk, distributionTable);
190
		ResultSet rs = state.getConfig().getSource().getResultSet(sql);
191
		try {
192
			while (rs.next()){
193
				Integer id;
194
				id = rs.getInt(parentCol);
195
				result.add(id);
196
			}
197
			return result;
198
		} catch (SQLException e) {
199
			e.printStackTrace();
200
			throw new RuntimeException(e);
201
		}
202
	}
203

    
204

    
205

    
206
	@Override
207
	public Map<Object, Map<String, ? extends CdmBase>> getRelatedObjectsForPartition(ResultSet rs, ErmsImportState state) {
208
		String nameSpace;
209
		Class<?> cdmClass;
210
		Set<String> idSet;
211
		Map<Object, Map<String, ? extends CdmBase>> result = new HashMap<Object, Map<String, ? extends CdmBase>>();
212

    
213
		try{
214
				Set<String> nameIdSet = new HashSet<String>();
215
				Set<String> referenceIdSet = new HashSet<String>();
216
				while (rs.next()){
217
	//				handleForeignKey(rs, nameIdSet, "PTNameFk");
218
	//				handleForeignKey(rs, referenceIdSet, "PTRefFk");
219
				}
220

    
221
			//reference map
222
//			nameSpace = "Reference";
223
//			cdmClass = Reference.class;
224
//			Map<String, Person> referenceMap = (Map<String, Person>)getCommonService().getSourcedObjectsByIdInSource(Person.class, teamIdSet, nameSpace);
225
//			result.put(Reference.class, referenceMap);
226

    
227
		} catch (SQLException e) {
228
			throw new RuntimeException(e);
229
		}
230
		return result;
231
	}
232

    
233
	@Override
234
	public TaxonBase<?> createObject(ResultSet rs, ErmsImportState state) throws SQLException {
235
		int statusId = rs.getInt("status_id");
236
//		Object accTaxonId = rs.getObject("tu_acctaxon");
237
		Integer meId = rs.getInt("id");
238

    
239
		String tuName = rs.getString("tu_name");
240
		String displayName = rs.getString("tu_displayname");
241

    
242
		String parent1Name = rs.getString("parent1name");
243
		Integer parent1Rank = rs.getInt("parent1rank");
244

    
245
		String parent2Name = rs.getString("parent2name");
246
		Integer parent2Rank = rs.getInt("parent2rank");
247

    
248
		String parent3Name = rs.getString("parent3name");
249
//		Integer parent3Rank = rs.getInt("parent3rank");
250

    
251
		NonViralName<?> taxonName = getTaxonName(rs, state);
252
		//set epithets
253
		if (taxonName.isGenus() || taxonName.isSupraGeneric()){
254
			taxonName.setGenusOrUninomial(tuName);
255
		}else if (taxonName.isInfraGeneric()){
256
			taxonName.setInfraGenericEpithet(tuName);
257
			taxonName.setGenusOrUninomial(parent1Name);
258
		}else if (taxonName.isSpecies()){
259
			taxonName.setSpecificEpithet(tuName);
260
			getGenusAndInfraGenus(parent1Name, parent2Name, parent1Rank, taxonName);
261
		}else if (taxonName.isInfraSpecific()){
262
			if (parent1Rank < 220){
263
				handleException(parent1Rank, taxonName, displayName, meId);
264
			}
265
			taxonName.setInfraSpecificEpithet(tuName);
266
			taxonName.setSpecificEpithet(parent1Name);
267
			getGenusAndInfraGenus(parent2Name, parent3Name, parent2Rank, taxonName);
268
		}else if (taxonName.getRank()== null){
269
			logger.warn("rank super domain still needs to be implemented. Used domain instead.");
270
			if ("Biota".equalsIgnoreCase(tuName)){
271
				Rank rank = Rank.DOMAIN();  //should be Superdomain
272
				taxonName.setRank(rank);
273
				taxonName.setGenusOrUninomial(tuName);
274
			}else{
275
				String warning = "TaxonName has no rank. Use namecache.";
276
				logger.warn(warning);
277
				taxonName.setNameCache(tuName);
278
			}
279

    
280
		}
281
		//e.g. Leucon [Platyhelminthes] ornatus
282
		if (containsBrackets(displayName)){
283
			taxonName.setNameCache(displayName);
284
			logger.warn("Set name cache: " +  displayName + ";id =" + meId);
285
		}
286

    
287
		//add original source for taxon name (taxon original source is added in mapper
288
		Reference citation = state.getTransactionalSourceReference();
289
		addOriginalSource(rs, taxonName, "id", NAME_NAMESPACE, citation);
290

    
291
		//old: if (statusId == 1){
292
		if (state.getAcceptedTaxaKeys().contains(meId)){
293
			Taxon result = Taxon.NewInstance(taxonName, citation);
294
			if (statusId != 1){
295
				logger.info("Taxon created as taxon but has status <> 1 ("+statusId+"): " + meId);
296
				handleNotAcceptedTaxon(result, statusId, state, rs);
297
			}
298
			return result;
299
		}else{
300
			return Synonym.NewInstance(taxonName, citation);
301
		}
302
	}
303

    
304

    
305

    
306
	private void handleNotAcceptedTaxon(Taxon taxon, int statusId, ErmsImportState state, ResultSet rs) throws SQLException {
307
		ExtensionType notAccExtensionType = getExtensionType(state, ErmsTransformer.uuidErmsTaxonStatus, "ERMS taxon status", "ERMS taxon status", "status", null);
308
		String statusName = rs.getString("status_name");
309

    
310
		if (statusId > 1){
311
			taxon.addExtension(statusName, notAccExtensionType);
312
		}
313
	}
314

    
315

    
316

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

    
328

    
329

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

    
339

    
340

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

    
357
	/**
358
	 * Returns an empty Taxon Name instance according to the given rank and kingdom.
359
	 * @param rs
360
	 * @return
361
	 * @throws SQLException
362
	 */
363
	private NonViralName<?> getTaxonName(ResultSet rs, ErmsImportState state) throws SQLException {
364
		NonViralName<?> result;
365
		Integer kingdomId = parseKingdomId(rs);
366
		Integer intRank = rs.getInt("tu_rank");
367

    
368
		NomenclaturalCode nc = ErmsTransformer.kingdomId2NomCode(kingdomId);
369
		Rank rank = null;
370
		if (kingdomId != null){
371
			rank = state.getRank(intRank, kingdomId);
372
		}else{
373
			logger.warn("KingdomId is null");
374
		}
375
		if (rank == null){
376
			logger.warn("Rank is null. KingdomId: " + kingdomId + ", rankId: " +  intRank);
377
		}
378
		if (nc != null){
379
			result = (NonViralName<?>)nc.getNewTaxonNameInstance(rank);
380
		}else{
381
			result = NonViralName.NewInstance(rank);
382
		}
383
		//cache strategy
384
		if (result instanceof ZoologicalName){
385
			NonViralNameDefaultCacheStrategy<?> cacheStrategy = PesiTaxonExport.zooNameStrategy;
386
			result.setCacheStrategy(cacheStrategy);
387
		}
388

    
389
		return result;
390
	}
391

    
392
	/**
393
	 * Returns the kingdom id by extracting it from the second character in the <code>tu_sp</code>
394
	 * attribute. If the attribute can not be parsed to a valid id <code>null</code>
395
	 * is returned. If the attribute is <code>null</code> the id of the record is returned.
396
	 * @param rs
397
	 * @return
398
	 * @throws SQLException
399
	 */
400
	private int parseKingdomId(ResultSet rs) throws SQLException {
401
		Integer result = null;
402
		String treeString = rs.getString("tu_sp");
403
		if (treeString != null){
404
			if (CdmUtils.isNotEmpty(treeString) && treeString.length() > 1){
405
				String strKingdom = treeString.substring(1,2);
406

    
407
				if (! treeString.substring(0, 1).equals("#") && ! treeString.substring(2, 3).equals("#") ){
408
					logger.warn("Tree string " + treeString + " has no recognized format");
409
				}else{
410
					try {
411
						result = Integer.valueOf(strKingdom);
412
					} catch (NumberFormatException e) {
413
						logger.warn("Kingdom string " + strKingdom + "could not be recognized as a valid number");
414
					}
415
				}
416
			}
417
		}else{
418
			Integer tu_id = rs.getInt("id");
419
			result = tu_id;
420
		}
421
		return result;
422
	}
423

    
424

    
425
	/* (non-Javadoc)
426
	 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doCheck(eu.etaxonomy.cdm.io.common.IImportConfigurator)
427
	 */
428
	@Override
429
	protected boolean doCheck(ErmsImportState state){
430
		IOValidator<ErmsImportState> validator = new ErmsTaxonImportValidator();
431
		return validator.validate(state);
432
	}
433

    
434

    
435
	/* (non-Javadoc)
436
	 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#isIgnore(eu.etaxonomy.cdm.io.common.IImportConfigurator)
437
	 */
438
	@Override
439
    protected boolean isIgnore(ErmsImportState state){
440
		return ! state.getConfig().isDoTaxa();
441
	}
442

    
443

    
444

    
445
}
(13-13/17)