Project

General

Profile

Download (22.8 KB) Statistics
| Branch: | Revision:
1 38e84b8e Andreas Müller
/**
2
* Copyright (C) 2007 EDIT
3 8422c0cd Andreas Müller
* European Distributed Institute of Taxonomy
4 38e84b8e Andreas Müller
* http://www.e-taxonomy.eu
5 8422c0cd Andreas Müller
*
6 38e84b8e Andreas Müller
* 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 bff8d9fe Andreas Müller
import org.apache.commons.lang3.StringUtils;
21 38e84b8e Andreas Müller
import org.apache.log4j.Logger;
22
import org.springframework.stereotype.Component;
23
24 33337032 Andreas Müller
import eu.etaxonomy.cdm.common.CdmUtils;
25
import eu.etaxonomy.cdm.io.common.DbImportStateBase;
26 38e84b8e Andreas Müller
import eu.etaxonomy.cdm.io.common.IOValidator;
27
import eu.etaxonomy.cdm.io.common.mapping.DbIgnoreMapper;
28 2eaad1b1 Andreas Müller
import eu.etaxonomy.cdm.io.common.mapping.DbImportAnnotationMapper;
29 38e84b8e Andreas Müller
import eu.etaxonomy.cdm.io.common.mapping.DbImportExtensionMapper;
30 e24d1470 Andreas Müller
import eu.etaxonomy.cdm.io.common.mapping.DbImportLsidMapper;
31 38e84b8e Andreas Müller
import eu.etaxonomy.cdm.io.common.mapping.DbImportMapping;
32 480528df Andreas Müller
import eu.etaxonomy.cdm.io.common.mapping.DbImportMarkerMapper;
33 651cb4bc Andreas Müller
import eu.etaxonomy.cdm.io.common.mapping.DbImportMethodMapper;
34 38e84b8e Andreas Müller
import eu.etaxonomy.cdm.io.common.mapping.DbImportObjectCreationMapper;
35
import eu.etaxonomy.cdm.io.common.mapping.DbImportStringMapper;
36
import eu.etaxonomy.cdm.io.common.mapping.DbNotYetImplementedMapper;
37
import eu.etaxonomy.cdm.io.common.mapping.IMappingImport;
38 33337032 Andreas Müller
import eu.etaxonomy.cdm.io.common.mapping.UndefinedTransformerMethodException;
39 2eaad1b1 Andreas Müller
import eu.etaxonomy.cdm.io.common.mapping.out.DbLastActionMapper;
40 38e84b8e Andreas Müller
import eu.etaxonomy.cdm.io.pesi.erms.validation.ErmsTaxonImportValidator;
41 496b12cc Andreas Müller
import eu.etaxonomy.cdm.io.pesi.out.PesiTaxonExport;
42 7e6fc953 Andreas Müller
import eu.etaxonomy.cdm.io.pesi.out.PesiTransformer;
43 2eaad1b1 Andreas Müller
import eu.etaxonomy.cdm.model.common.AnnotationType;
44 38e84b8e Andreas Müller
import eu.etaxonomy.cdm.model.common.CdmBase;
45 07928004 Andreas Müller
import eu.etaxonomy.cdm.model.common.ExtensionType;
46 33337032 Andreas Müller
import eu.etaxonomy.cdm.model.common.Language;
47 2eaad1b1 Andreas Müller
import eu.etaxonomy.cdm.model.common.MarkerType;
48 38e84b8e Andreas Müller
import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
49 33337032 Andreas Müller
import eu.etaxonomy.cdm.model.name.NomenclaturalStatusType;
50 38e84b8e Andreas Müller
import eu.etaxonomy.cdm.model.name.Rank;
51 51688d00 Andreas Müller
import eu.etaxonomy.cdm.model.name.TaxonName;
52 bbeda5af Katja Luther
import eu.etaxonomy.cdm.model.name.TaxonNameFactory;
53 3dee8a19 Andreas Müller
import eu.etaxonomy.cdm.model.reference.Reference;
54 38e84b8e Andreas Müller
import eu.etaxonomy.cdm.model.taxon.Synonym;
55
import eu.etaxonomy.cdm.model.taxon.Taxon;
56
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
57 ab2f9bc5 Andreas Müller
import eu.etaxonomy.cdm.strategy.cache.name.TaxonNameDefaultCacheStrategy;
58 38e84b8e Andreas Müller
59
/**
60
 * @author a.mueller
61 a13538c8 Andreas Müller
 * @since 20.02.2010
62 38e84b8e Andreas Müller
 */
63
@Component
64 bff8d9fe Andreas Müller
public class ErmsTaxonImport
65
        extends ErmsImportBase<TaxonBase<?>>
66
        implements IMappingImport<TaxonBase<?>, ErmsImportState>{
67
68
    private static final long serialVersionUID = -7111568277264140051L;
69
    private static final Logger logger = Logger.getLogger(ErmsTaxonImport.class);
70 8422c0cd Andreas Müller
71 3dbf0f71 Andreas Müller
	private DbImportMapping<ErmsImportState, ErmsImportConfigurator> mapping;
72 8422c0cd Andreas Müller
73 38e84b8e Andreas Müller
	private static final String pluralString = "taxa";
74
	private static final String dbTableName = "tu";
75 3dbf0f71 Andreas Müller
	private static final Class<?> cdmTargetClass = TaxonBase.class;
76 38e84b8e Andreas Müller
77
	public ErmsTaxonImport(){
78
		super(pluralString, dbTableName, cdmTargetClass);
79
	}
80 8422c0cd Andreas Müller
81 d7f95f72 Andreas Müller
	@Override
82
	protected String getIdQuery() {
83 8a133607 Andreas Müller
		String strQuery = " SELECT id FROM tu " ;  //WHERE id NOT IN (147415) for now we exclude Monera as it has no children and is unclear what classification it has. In ERMS it is alternative accepted name (in https://en.wikipedia.org/wiki/Monera it might be a super taxon to bacteria).
84 d7f95f72 Andreas Müller
		return strQuery;
85
	}
86 38e84b8e Andreas Müller
87 8422c0cd Andreas Müller
	@Override
88
    protected DbImportMapping<ErmsImportState, ErmsImportConfigurator> getMapping() {
89 38e84b8e Andreas Müller
		if (mapping == null){
90 4d0649fd Andreas Müller
			mapping = new DbImportMapping<>();
91 8422c0cd Andreas Müller
92 38e84b8e Andreas Müller
			mapping.addMapper(DbImportObjectCreationMapper.NewInstance(this, "id", TAXON_NAMESPACE)); //id + tu_status
93 8422c0cd Andreas Müller
			mapping.addMapper(DbImportLsidMapper.NewInstance("GUID", "lsid"));
94 e24d1470 Andreas Müller
95 33f66be4 Andreas Müller
			UUID tsnUuid = ErmsTransformer.uuidExtTsn;
96 8422c0cd Andreas Müller
			ExtensionType tsnExtType = getExtensionType(tsnUuid, "TSN", "TSN", "TSN");
97 07928004 Andreas Müller
			mapping.addMapper(DbImportExtensionMapper.NewInstance("tsn", tsnExtType));
98 38e84b8e Andreas Müller
//			mapping.addMapper(DbImportStringMapper.NewInstance("tu_name", "(NonViralName)name.nameCache"));
99 8422c0cd Andreas Müller
100 649ffe58 Andreas Müller
			ExtensionType displayNameExtType = getExtensionType(ErmsTransformer.uuidExtDisplayName, "display name", "display name", "display name");
101 07928004 Andreas Müller
			mapping.addMapper(DbImportExtensionMapper.NewInstance("tu_displayname", displayNameExtType));
102 bb4404d2 Andreas Müller
            //Ignore fuzzyName
103
            //  ExtensionType fuzzyNameExtType = getExtensionType(ErmsTransformer.uuidExtFuzzyName, "fuzzy name", "fuzzy name", "fuzzy name");
104
            //  mapping.addMapper(DbImportExtensionMapper.NewInstance("tu_fuzzyname", fuzzyNameExtType));
105 4d0649fd Andreas Müller
			mapping.addMapper(DbImportStringMapper.NewInstance("tu_authority", "name.authorshipCache"));
106 8422c0cd Andreas Müller
107 649ffe58 Andreas Müller
			ExtensionType fossilStatusExtType = getExtensionType(ErmsTransformer.uuidExtFossilStatus, "fossil status", "fossil status", "fos. stat.");
108 07928004 Andreas Müller
			mapping.addMapper(DbImportExtensionMapper.NewInstance("fossil_name", fossilStatusExtType));
109 e24d1470 Andreas Müller
110 649ffe58 Andreas Müller
			ExtensionType unacceptExtType = getExtensionType(ErmsTransformer.uuidExtUnacceptReason, "unaccept reason", "unaccept reason", "reason");
111 07928004 Andreas Müller
			mapping.addMapper(DbImportExtensionMapper.NewInstance("tu_unacceptreason", unacceptExtType));
112 8422c0cd Andreas Müller
113 649ffe58 Andreas Müller
			ExtensionType qualityStatusExtType = getExtensionType(ErmsTransformer.uuidExtQualityStatus, "quality status", "quality status", "quality status");
114 07928004 Andreas Müller
			mapping.addMapper(DbImportExtensionMapper.NewInstance("qualitystatus_name", qualityStatusExtType)); //checked by Tax Editor ERMS1.1, Added by db management team (2x), checked by Tax Editor
115 480528df Andreas Müller
116 2ae4e7ca Andreas Müller
			ExtensionType cacheCitationExtType = getExtensionType(PesiTransformer.uuidExtCacheCitation, "cache_citation", "quality status", "cache_citation");
117
            mapping.addMapper(DbImportExtensionMapper.NewInstance("cache_citation", cacheCitationExtType));
118
119
            //flags
120 480528df Andreas Müller
			mapping.addMapper(DbImportMarkerMapper.NewInstance("tu_marine", ErmsTransformer.uuidMarkerMarine, "marine", "marine", "marine", null));
121
			mapping.addMapper(DbImportMarkerMapper.NewInstance("tu_brackish", ErmsTransformer.uuidMarkerBrackish, "brackish", "brackish", "brackish", null));
122
			mapping.addMapper(DbImportMarkerMapper.NewInstance("tu_fresh", ErmsTransformer.uuidMarkerFreshwater, "freshwater", "fresh", "fresh", null));
123
			mapping.addMapper(DbImportMarkerMapper.NewInstance("tu_terrestrial", ErmsTransformer.uuidMarkerTerrestrial, "terrestrial", "terrestrial", "terrestrial", null));
124 7e6fc953 Andreas Müller
125
			//last action, species expert
126
			ExtensionType speciesExpertNameExtType = getExtensionType(PesiTransformer.uuidExtSpeciesExpertName, "species expert name", "species expert name", "species expert name");
127
            mapping.addMapper(DbImportExtensionMapper.NewInstance("ExpertName", speciesExpertNameExtType)); //according to sql script ExpertName maps to SpeciesExpertName in ERMS
128
            AnnotationType lastActionDateType = getAnnotationType(DbLastActionMapper.uuidAnnotationTypeLastActionDate, "Last action date", "Last action date", null);
129 2eaad1b1 Andreas Müller
			mapping.addMapper(DbImportAnnotationMapper.NewInstance("lastActionDate", lastActionDateType));
130
            AnnotationType lastActionType = getAnnotationType(DbLastActionMapper.uuidAnnotationTypeLastAction, "Last action", "Last action", null);
131
            MarkerType hasNoLastActionMarkerType = getMarkerType(DbLastActionMapper.uuidMarkerTypeHasNoLastAction, "has no last action", "No last action information available", "no last action");
132
            mapping.addMapper(DbImportAnnotationMapper.NewInstance("lastAction", lastActionType, hasNoLastActionMarkerType));
133 480528df Andreas Müller
134 651cb4bc Andreas Müller
            //titleCache compare
135
            mapping.addMapper(DbImportMethodMapper.NewDefaultInstance(this, "testTitleCache", ErmsImportState.class));
136
137 74fb14c4 Andreas Müller
			//not yet implemented
138 8422c0cd Andreas Müller
			mapping.addMapper(DbNotYetImplementedMapper.NewInstance("tu_sp", "included in rank/object creation"));
139
140 38e84b8e Andreas Müller
			//ignore
141
			mapping.addMapper(DbIgnoreMapper.NewInstance("tu_fossil", "tu_fossil implemented as foreign key"));
142 8422c0cd Andreas Müller
143 38e84b8e Andreas Müller
		}
144
		return mapping;
145
	}
146
147
	@Override
148
	protected String getRecordQuery(ErmsImportConfigurator config) {
149 651cb4bc Andreas Müller
		String strSelect = " SELECT tu.*, parent1.tu_name AS parent1name, parent2.tu_name AS parent2name, parent3.tu_name AS parent3name, parent4.tu_name AS parent4name, " +
150 7e6fc953 Andreas Müller
		            " parent1.tu_rank AS parent1rank, parent2.tu_rank AS parent2rank, parent3.tu_rank AS parent3rank, " +
151
		            " status.status_id as status_id, status.status_name, fossil.fossil_name, qualitystatus.qualitystatus_name," +
152
		            " s.sessiondate lastActionDate, a.action_name lastAction, s.ExpertName ";
153 8422c0cd Andreas Müller
		String strFrom = " FROM tu  LEFT OUTER JOIN  tu AS parent1 ON parent1.id = tu.tu_parent " +
154
				" LEFT OUTER JOIN   tu AS parent2  ON parent2.id = parent1.tu_parent " +
155
				" LEFT OUTER JOIN tu AS parent3 ON parent2.tu_parent = parent3.id " +
156 651cb4bc Andreas Müller
				" LEFT OUTER JOIN tu AS parent4 ON parent3.tu_parent = parent4.id " +
157
                " LEFT OUTER JOIN status ON tu.tu_status = status.status_id " +
158 38e84b8e Andreas Müller
				" LEFT OUTER JOIN fossil ON tu.tu_fossil = fossil.fossil_id " +
159 2eaad1b1 Andreas Müller
				" LEFT OUTER JOIN qualitystatus ON tu.tu_qualitystatus = qualitystatus.id " +
160 7e6fc953 Andreas Müller
				" LEFT OUTER JOIN tu_sessions ts ON ts.tu_id = tu.id " +
161
                " LEFT OUTER JOIN [sessions] s ON s.id = ts.session_id " +
162
                " LEFT OUTER JOIN actions a ON a.id = ts.action_id ";
163 38e84b8e Andreas Müller
		String strWhere = " WHERE ( tu.id IN (" + ID_LIST_TOKEN + ") )";
164 7e6fc953 Andreas Müller
		String strOrderBy = " ORDER BY tu.id, s.sessiondate DESC, a.id DESC ";
165
		String strRecordQuery = strSelect + strFrom + strWhere + strOrderBy;
166 38e84b8e Andreas Müller
		return strRecordQuery;
167
	}
168 8422c0cd Andreas Müller
169 38e84b8e Andreas Müller
	@Override
170 c59ecc4a Andreas Müller
	protected void doInvoke(ErmsImportState state) {
171 480528df Andreas Müller
		state.setAcceptedTaxaKeys(getAcceptedTaxaKeys(state));
172 8422c0cd Andreas Müller
173 38e84b8e Andreas Müller
		//first path
174 c59ecc4a Andreas Müller
		super.doInvoke(state);
175
		return;
176 38e84b8e Andreas Müller
	}
177
178 7e6fc953 Andreas Müller
	Integer lastTaxonId = null;
179
    @Override
180
    protected boolean ignoreRecord(ResultSet rs) throws SQLException {
181
        Integer id = rs.getInt("id");
182
        boolean result = id.equals(lastTaxonId);
183
        lastTaxonId = id;
184
        return result;
185
    }
186
187 e74f380f Andreas Müller
	private Set<Integer> getAcceptedTaxaKeys(ErmsImportState state) {
188 4d0649fd Andreas Müller
		Set<Integer> result = new HashSet<>();
189 c1a5c2bd Andreas Müller
		String idCol = " id ";
190 12fc8d50 Andreas Müller
		String tuFk = "tu_id";
191
		String vernacularsTable = "vernaculars";
192
		String distributionTable = "dr";
193 ddc988ed Andreas Müller
		String notesTable = "notes";
194 4d0649fd Andreas Müller
		String sql =
195 41cf69c5 Andreas Müller
		        "          SELECT id FROM tu WHERE tu_acctaxon is NULL" //id of taxa not having accepted taxon
196
		        + " UNION  SELECT DISTINCT tu_acctaxon FROM tu "  //fk to accepted taxon (either the accepted taxon or the taxon itself, if accepted)
197
		        + " UNION  SELECT syn.id FROM tu syn INNER JOIN tu acc ON syn.tu_acctaxon = acc.id WHERE syn.id = acc.tu_parent AND acc.id <> syn.id "  //see also ErmsTaxonRelationImport.isAccepted, there are some autonyms being the accepted taxon of there own parents
198
                + " UNION  SELECT DISTINCT %s FROM %s " //vernaculars
199 ddc988ed Andreas Müller
		        + " UNION  SELECT DISTINCT %s FROM %s "  //distributions
200
		        + " UNION  SELECT DISTINCT %s FROM %s ";  //notes
201 8422c0cd Andreas Müller
		sql = String.format(sql,
202 41cf69c5 Andreas Müller
		        tuFk, vernacularsTable,
203 ddc988ed Andreas Müller
				tuFk, distributionTable,
204
				tuFk, notesTable);
205 07928004 Andreas Müller
		ResultSet rs = state.getConfig().getSource().getResultSet(sql);
206
		try {
207
			while (rs.next()){
208
				Integer id;
209 1bbfa4c0 Andreas Müller
				id = rs.getInt(idCol.trim());
210 07928004 Andreas Müller
				result.add(id);
211
			}
212
			return result;
213
		} catch (SQLException e) {
214
			e.printStackTrace();
215
			throw new RuntimeException(e);
216
		}
217
	}
218
219 9900f429 Andreas Müller
	@Override
220
	public Map<Object, Map<String, ? extends CdmBase>> getRelatedObjectsForPartition(ResultSet rs, ErmsImportState state) {
221 23801854 Andreas Müller
		//currently no referencing objects needed
222
	    Map<Object, Map<String, ? extends CdmBase>> result = new HashMap<>();
223 38e84b8e Andreas Müller
		return result;
224
	}
225 8422c0cd Andreas Müller
226 9900f429 Andreas Müller
	@Override
227 3dbf0f71 Andreas Müller
	public TaxonBase<?> createObject(ResultSet rs, ErmsImportState state) throws SQLException {
228 38e84b8e Andreas Müller
		int statusId = rs.getInt("status_id");
229 3dbf0f71 Andreas Müller
//		Object accTaxonId = rs.getObject("tu_acctaxon");
230 07928004 Andreas Müller
		Integer meId = rs.getInt("id");
231 8422c0cd Andreas Müller
232 60d45927 Andreas Müller
        TaxonName taxonName = getTaxonName(rs, state);
233
		fillTaxonName(taxonName, rs, state, meId);
234 33337032 Andreas Müller
235
		//add original source for taxon name (taxon original source is added in mapper)
236
		Reference citation = state.getTransactionalSourceReference();
237
		addOriginalSource(rs, taxonName, "id", NAME_NAMESPACE, citation);
238
239
		TaxonBase<?> result;
240
		//handle accepted<-> synonym, we create more accepted taxa as we need them within the tree or to attache factual data
241
		if (state.getAcceptedTaxaKeys().contains(meId)){
242
			Taxon taxon = Taxon.NewInstance(taxonName, citation);
243
			if (statusId != 1){
244
				logger.info("Taxon created as taxon but has status <> 1 ("+statusId+"): " + meId);
245
				handleNotAcceptedTaxon(taxon, statusId, state, rs);
246
			}
247
			result = taxon;
248
		}else{
249
			result = Synonym.NewInstance(taxonName, citation);
250
		}
251
252
		handleNameStatus(result.getName(), rs, state);
253
		return result;
254
	}
255
256
    private void handleNameStatus(TaxonName name, ResultSet rs, ErmsImportState state) throws SQLException {
257
        NomenclaturalStatusType nomStatus = null;
258
        int tuStatus = rs.getInt("tu_status");
259 7599c655 Andreas Müller
        //the order is bottom up from SQL script as there values are overriden from top to bottom
260
        if (tuStatus == 8){
261
            //species inquirenda
262
            nomStatus = getNomenclaturalStatusType(state, ErmsTransformer.uuidNomStatusSpeciesInquirenda, "species inquirenda", "species inquirenda", null, Language.LATIN(), null);
263 33337032 Andreas Müller
        }else if (tuStatus == 7){
264
            //temporary name
265
            nomStatus = getNomenclaturalStatusType(state, PesiTransformer.uuidNomStatusTemporaryName, "temporary name", "temporary name", null, Language.ENGLISH(), null);
266 7599c655 Andreas Müller
        }else if (tuStatus == 6){
267
            //nomen dubium
268
            nomStatus = NomenclaturalStatusType.DOUBTFUL();
269
        }else if (tuStatus == 5){
270
            //"alternate representation"
271
            nomStatus = getNomenclaturalStatusType(state, ErmsTransformer.uuidNomStatusAlternateRepresentation, "alternate representation", "alternate representation", null, Language.ENGLISH(), null);
272
        }else if (tuStatus == 3){
273
            //nomen nudum
274
            nomStatus = NomenclaturalStatusType.NUDUM();
275 33337032 Andreas Müller
        }
276
        if (nomStatus == null){
277 7599c655 Andreas Müller
            //IN SQL Script it is set first by unacceptreason and then overriden if above tu_status exists
278 33337032 Andreas Müller
            String unacceptReason = rs.getString("tu_unacceptreason");
279
            try {
280
                nomStatus = state.getTransformer().getNomenclaturalStatusByKey(unacceptReason);
281
            } catch (UndefinedTransformerMethodException e) {logger.warn("Unhandled method");
282
            }
283
        }
284
        if (nomStatus != null){
285
            name.addStatus(nomStatus, null, null);
286
        }
287
    }
288
289 60d45927 Andreas Müller
    private TaxonName fillTaxonName(TaxonName taxonName, ResultSet rs, ErmsImportState state, Integer meId) throws SQLException {
290 33337032 Andreas Müller
        String tuName = rs.getString("tu_name");
291 55da90fc Andreas Müller
		String displayName = rs.getString("tu_displayname").trim();
292 8422c0cd Andreas Müller
293 38e84b8e Andreas Müller
		String parent1Name = rs.getString("parent1name");
294
		Integer parent1Rank = rs.getInt("parent1rank");
295 8422c0cd Andreas Müller
296 38e84b8e Andreas Müller
		String parent2Name = rs.getString("parent2name");
297
		Integer parent2Rank = rs.getInt("parent2rank");
298 8422c0cd Andreas Müller
299 38e84b8e Andreas Müller
		String parent3Name = rs.getString("parent3name");
300 651cb4bc Andreas Müller
		Integer parent3Rank = rs.getInt("parent3rank");
301
302
	    String parent4Name = rs.getString("parent4name");
303 8422c0cd Andreas Müller
304 38e84b8e Andreas Müller
		//set epithets
305
		if (taxonName.isGenus() || taxonName.isSupraGeneric()){
306
			taxonName.setGenusOrUninomial(tuName);
307
		}else if (taxonName.isInfraGeneric()){
308
			taxonName.setInfraGenericEpithet(tuName);
309
			taxonName.setGenusOrUninomial(parent1Name);
310
		}else if (taxonName.isSpecies()){
311
			taxonName.setSpecificEpithet(tuName);
312
			getGenusAndInfraGenus(parent1Name, parent2Name, parent1Rank, taxonName);
313
		}else if (taxonName.isInfraSpecific()){
314
			if (parent1Rank < 220){
315 480528df Andreas Müller
				handleException(parent1Rank, taxonName, displayName, meId);
316 38e84b8e Andreas Müller
			}
317
			taxonName.setInfraSpecificEpithet(tuName);
318 651cb4bc Andreas Müller
			if (parent1Rank > 220){  //parent is still infraspecific
319
			    taxonName.setSpecificEpithet(parent2Name);
320
			    getGenusAndInfraGenus(parent3Name, parent4Name, parent3Rank, taxonName);
321
			}else{
322
			    //default
323
			    taxonName.setSpecificEpithet(parent1Name);
324
			    getGenusAndInfraGenus(parent2Name, parent3Name, parent2Rank, taxonName);
325
			}
326 38e84b8e Andreas Müller
		}else if (taxonName.getRank()== null){
327
			if ("Biota".equalsIgnoreCase(tuName)){
328
				Rank rank = Rank.DOMAIN();  //should be Superdomain
329
				taxonName.setRank(rank);
330
				taxonName.setGenusOrUninomial(tuName);
331
			}else{
332
				String warning = "TaxonName has no rank. Use namecache.";
333
				logger.warn(warning);
334
				taxonName.setNameCache(tuName);
335
			}
336
		}
337 33f66be4 Andreas Müller
338 38e84b8e Andreas Müller
		//e.g. Leucon [Platyhelminthes] ornatus
339
		if (containsBrackets(displayName)){
340
			taxonName.setNameCache(displayName);
341 72fbf719 Andreas Müller
			logger.warn("Set name cache: " +  displayName + "; id =" + meId);
342 38e84b8e Andreas Müller
		}
343 651cb4bc Andreas Müller
        if (!taxonName.getNameCache().equals(displayName)){
344 2f628c0c Andreas Müller
            int pos = CdmUtils.diffIndex(taxonName.getNameCache(), displayName);
345
            logger.warn("Computed name cache differs at "+pos+".\n Computed   : " + taxonName.getNameCache()+"\n DisplayName: " +displayName);
346 651cb4bc Andreas Müller
            taxonName.setNameCache(displayName, true);
347
        }
348 7e83bb1d Andreas Müller
		taxonName.getTitleCache();
349 651cb4bc Andreas Müller
        return taxonName;
350
    }
351 8422c0cd Andreas Müller
352 651cb4bc Andreas Müller
    @SuppressWarnings("unused")  //used by MethodMapper
353
    private static TaxonBase<?> testTitleCache(ResultSet rs, ErmsImportState state) throws SQLException{
354
        TaxonBase<?> taxon = (TaxonBase<?>)state.getRelatedObject(DbImportStateBase.CURRENT_OBJECT_NAMESPACE, DbImportStateBase.CURRENT_OBJECT_ID);
355
        TaxonName taxonName = taxon.getName();
356
         String displayName = rs.getString("tu_displayname");
357 54a3d685 Andreas Müller
         displayName = displayName == null ? null : displayName.trim();
358 651cb4bc Andreas Müller
         String titleCache = taxonName.resetTitleCache(); //calling titleCache should always be kept to have a computed titleCache in the CDM DB.
359
         String expectedTitleCache = getExpectedTitleCache(rs);
360
         //TODO check titleCache, but beware of autonyms
361
         if (!titleCache.equals(expectedTitleCache)){
362 39d481af Andreas Müller
             int pos = CdmUtils.diffIndex(titleCache, expectedTitleCache);
363
             logger.warn("Computed title cache differs at "+pos+".\n Computed             : " + titleCache + "\n DisplayName+Authority: " + expectedTitleCache);
364 651cb4bc Andreas Müller
             taxonName.setNameCache(displayName, true);
365
         }
366
         return taxon;
367
     }
368
369
     //see also PesiErmsValidation.srcFullName()
370
     private static String getExpectedTitleCache(ResultSet srcRs) throws SQLException {
371
        String result;
372
        String epi = srcRs.getString("tu_name");
373
        epi = " a" + epi;
374
        String display = srcRs.getString("tu_displayname");
375
        String sp = srcRs.getString("tu_sp");
376
        if (display.indexOf(epi) != display.lastIndexOf(epi) && !sp.startsWith("#2#")){ //homonym, animal
377
            result = srcRs.getString("tu_displayname").replaceFirst(epi+" ", CdmUtils.concat(" ", " "+epi, srcRs.getString("tu_authority")))+" ";
378
        }else{
379
            result = CdmUtils.concat(" ", srcRs.getString("tu_displayname"), srcRs.getString("tu_authority"));
380
        }
381 55da90fc Andreas Müller
        return result.trim();
382 651cb4bc Andreas Müller
    }
383 38e84b8e Andreas Müller
384 3dbf0f71 Andreas Müller
	private void handleNotAcceptedTaxon(Taxon taxon, int statusId, ErmsImportState state, ResultSet rs) throws SQLException {
385
		ExtensionType notAccExtensionType = getExtensionType(state, ErmsTransformer.uuidErmsTaxonStatus, "ERMS taxon status", "ERMS taxon status", "status", null);
386
		String statusName = rs.getString("status_name");
387 8422c0cd Andreas Müller
388 3dbf0f71 Andreas Müller
		if (statusId > 1){
389
			taxon.addExtension(statusName, notAccExtensionType);
390
		}
391
	}
392
393 51688d00 Andreas Müller
	private void handleException(Integer parent1Rank, TaxonName taxonName, String displayName, Integer meId) {
394 480528df Andreas Müller
		logger.warn("Parent of infra specific taxon is higher than species. Used nameCache: " + displayName +  "; id=" + meId) ;
395 38e84b8e Andreas Müller
		taxonName.setNameCache(displayName);
396
	}
397
398
	private boolean containsBrackets(String displayName) {
399
		int index = displayName.indexOf("[");
400
		return (index > -1);
401
	}
402
403 51688d00 Andreas Müller
	private void getGenusAndInfraGenus(String parentName, String grandParentName, Integer parent1Rank, TaxonName taxonName) {
404 38e84b8e Andreas Müller
		if (parent1Rank <220 && parent1Rank > 180){
405
			//parent is infrageneric
406
			taxonName.setInfraGenericEpithet(parentName);
407
			taxonName.setGenusOrUninomial(grandParentName);
408
		}else{
409
			taxonName.setGenusOrUninomial(parentName);
410
		}
411
	}
412
413
	/**
414 07928004 Andreas Müller
	 * Returns an empty Taxon Name instance according to the given rank and kingdom.
415 38e84b8e Andreas Müller
	 */
416 51688d00 Andreas Müller
	private TaxonName getTaxonName(ResultSet rs, ErmsImportState state) throws SQLException {
417
	    TaxonName result;
418 cd79d676 Andreas Müller
		int kingdomId = parseKingdomId(rs);
419 38e84b8e Andreas Müller
		Integer intRank = rs.getInt("tu_rank");
420 8422c0cd Andreas Müller
421 38e84b8e Andreas Müller
		NomenclaturalCode nc = ErmsTransformer.kingdomId2NomCode(kingdomId);
422
		Rank rank = null;
423 cd79d676 Andreas Müller
		rank = state.getRank(intRank, kingdomId);
424
425 38e84b8e Andreas Müller
		if (rank == null){
426
			logger.warn("Rank is null. KingdomId: " + kingdomId + ", rankId: " +  intRank);
427
		}
428
		if (nc != null){
429 51688d00 Andreas Müller
			result = nc.getNewTaxonNameInstance(rank);
430 38e84b8e Andreas Müller
		}else{
431 bbeda5af Katja Luther
			result = TaxonNameFactory.NewNonViralInstance(rank);
432 38e84b8e Andreas Müller
		}
433 496b12cc Andreas Müller
		//cache strategy
434 51688d00 Andreas Müller
		if (result.isZoological()){
435 ab2f9bc5 Andreas Müller
		    TaxonNameDefaultCacheStrategy cacheStrategy = PesiTaxonExport.zooNameStrategy;
436 496b12cc Andreas Müller
			result.setCacheStrategy(cacheStrategy);
437
		}
438 8422c0cd Andreas Müller
439 38e84b8e Andreas Müller
		return result;
440
	}
441
442
	/**
443 8422c0cd Andreas Müller
	 * Returns the kingdom id by extracting it from the second character in the <code>tu_sp</code>
444 38e84b8e Andreas Müller
	 * attribute. If the attribute can not be parsed to a valid id <code>null</code>
445
	 * is returned. If the attribute is <code>null</code> the id of the record is returned.
446
	 * @param rs
447
	 * @return
448
	 * @throws SQLException
449
	 */
450
	private int parseKingdomId(ResultSet rs) throws SQLException {
451
		String treeString = rs.getString("tu_sp");
452
		if (treeString != null){
453 cd79d676 Andreas Müller
		    if (StringUtils.isNotBlank(treeString) && treeString.length() > 1){
454 38e84b8e Andreas Müller
				String strKingdom = treeString.substring(1,2);
455 8422c0cd Andreas Müller
456 38e84b8e Andreas Müller
				if (! treeString.substring(0, 1).equals("#") && ! treeString.substring(2, 3).equals("#") ){
457 cd79d676 Andreas Müller
					String message = "Tree string " + treeString + " has no recognized format";
458
                    logger.warn(message);
459
                    throw new RuntimeException(message);
460 38e84b8e Andreas Müller
				}else{
461
					try {
462 cd79d676 Andreas Müller
						return Integer.valueOf(strKingdom);
463 38e84b8e Andreas Müller
					} catch (NumberFormatException e) {
464 cd79d676 Andreas Müller
					    String message = "Kingdom string " + strKingdom + "could not be recognized as a valid number";
465
						logger.warn(message);
466
						throw new RuntimeException(message);
467 38e84b8e Andreas Müller
					}
468
				}
469 cd79d676 Andreas Müller
			}else{
470
                String message = "Tree string for kingdom recognition is to short: " + treeString;
471
                logger.warn(message);
472
                throw new RuntimeException(message);
473 38e84b8e Andreas Müller
			}
474
		}else{
475 cd79d676 Andreas Müller
			int tu_id = rs.getInt("id");
476
			return tu_id;
477 38e84b8e Andreas Müller
		}
478
	}
479
480
	@Override
481
	protected boolean doCheck(ErmsImportState state){
482
		IOValidator<ErmsImportState> validator = new ErmsTaxonImportValidator();
483
		return validator.validate(state);
484
	}
485 8422c0cd Andreas Müller
486
	@Override
487
    protected boolean isIgnore(ErmsImportState state){
488 38e84b8e Andreas Müller
		return ! state.getConfig().isDoTaxa();
489
	}
490
}