Project

General

Profile

Download (13.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.berlinModel.in;
11

    
12
import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.T_STATUS_ACCEPTED;
13
import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.T_STATUS_PARTIAL_SYN;
14
import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.T_STATUS_PRO_PARTE_SYN;
15
import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.T_STATUS_SYNONYM;
16
import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.T_STATUS_UNRESOLVED;
17

    
18
import java.lang.reflect.Method;
19
import java.sql.ResultSet;
20
import java.sql.SQLException;
21
import java.util.HashMap;
22
import java.util.HashSet;
23
import java.util.Map;
24
import java.util.Set;
25
import java.util.UUID;
26

    
27
import org.apache.commons.lang.StringUtils;
28
import org.apache.log4j.Logger;
29
import org.springframework.stereotype.Component;
30

    
31
import eu.etaxonomy.cdm.database.update.DatabaseTypeNotSupportedException;
32
import eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer;
33
import eu.etaxonomy.cdm.io.berlinModel.in.validation.BerlinModelTaxonImportValidator;
34
import eu.etaxonomy.cdm.io.common.IOValidator;
35
import eu.etaxonomy.cdm.io.common.ResultSetPartitioner;
36
import eu.etaxonomy.cdm.model.agent.Person;
37
import eu.etaxonomy.cdm.model.common.CdmBase;
38
import eu.etaxonomy.cdm.model.common.Extension;
39
import eu.etaxonomy.cdm.model.common.ExtensionType;
40
import eu.etaxonomy.cdm.model.common.Language;
41
import eu.etaxonomy.cdm.model.common.Marker;
42
import eu.etaxonomy.cdm.model.common.MarkerType;
43
import eu.etaxonomy.cdm.model.description.Feature;
44
import eu.etaxonomy.cdm.model.description.TaxonDescription;
45
import eu.etaxonomy.cdm.model.description.TextData;
46
import eu.etaxonomy.cdm.model.name.TaxonName;
47
import eu.etaxonomy.cdm.model.reference.Reference;
48
import eu.etaxonomy.cdm.model.taxon.Synonym;
49
import eu.etaxonomy.cdm.model.taxon.Taxon;
50
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
51

    
52

    
53
/**
54
 * @author a.mueller
55
 * @since 20.03.2008
56
 */
57
@Component
58
public class BerlinModelTaxonImport  extends BerlinModelImportBase {
59
    private static final long serialVersionUID = -1186364983750790695L;
60

    
61
    private static final Logger logger = Logger.getLogger(BerlinModelTaxonImport.class);
62

    
63
	public static final String NAMESPACE = "Taxon";
64

    
65
	private static final String pluralString = "Taxa";
66
	private static final String dbTableName = "PTaxon";
67

    
68
	/**
69
	 * How should the publish flag in table PTaxon be interpreted
70
	 * NO_MARKER: No marker is set
71
	 * ONLY_FALSE:
72
	 */
73
	public enum PublishMarkerChooser{
74
		NO_MARKER,
75
		ONLY_FALSE,
76
		ONLY_TRUE,
77
		ALL;
78

    
79
		boolean doMark(boolean value){
80
			if (value == true){
81
				return this == ALL || this == ONLY_TRUE;
82
			}else{
83
				return this == ALL || this == ONLY_FALSE;
84
			}
85
		}
86
	}
87

    
88
	public BerlinModelTaxonImport(){
89
		super(dbTableName, pluralString);
90
	}
91

    
92
	@Override
93
	protected String getIdQuery(BerlinModelImportState state) {
94
		String sqlSelect = " SELECT RIdentifier";
95
		String taxonTable = state.getConfig().getTaxonTable();
96
		String sqlFrom = String.format(" FROM %s ", taxonTable);
97
		String sqlWhere = "";
98

    
99
		String sql = sqlSelect + " " + sqlFrom + " " + sqlWhere ;
100
		return sql;
101
	}
102

    
103
	@Override
104
	protected String getRecordQuery(BerlinModelImportConfigurator config) {
105
		String sqlSelect = " SELECT pt.*  ";
106
		String sqlFrom = " FROM PTaxon pt ";
107
		if (isEuroMed(config) ){
108
			sqlFrom = " FROM PTaxon AS pt " +
109
							" INNER JOIN v_cdm_exp_taxaAll AS em ON pt.RIdentifier = em.RIdentifier " +
110
							" LEFT OUTER JOIN Reference r ON pt.LastScrutinyFk = r.RefId ";
111
			sqlSelect += " , em.MA, r.RefCache as LastScrutiny ";
112
		}
113

    
114

    
115
		String sqlWhere = " WHERE ( pt.RIdentifier IN (" + ID_LIST_TOKEN + ") )";
116

    
117
		String strRecordQuery =sqlSelect + " " + sqlFrom + " " + sqlWhere ;
118
//			" SELECT * " +
119
//			" FROM PTaxon " + state.getConfig().getTaxonTable();
120
//			" WHERE ( RIdentifier IN (" + ID_LIST_TOKEN + ") )";
121
		return strRecordQuery;
122
	}
123

    
124
	private boolean isEuroMed(BerlinModelImportConfigurator config) {
125
		return config.getTaxonTable().trim().equals("v_cdm_exp_taxaAll");
126
	}
127

    
128
	@Override
129
	protected boolean doCheck(BerlinModelImportState state){
130
		IOValidator<BerlinModelImportState> validator = new BerlinModelTaxonImportValidator();
131
		return validator.validate(state);
132
	}
133

    
134
	@Override
135
	public boolean doPartition(ResultSetPartitioner partitioner, BerlinModelImportState state) {
136
		boolean success = true ;
137

    
138
		BerlinModelImportConfigurator config = state.getConfig();
139
		Set<TaxonBase> taxaToSave = new HashSet<>();
140
		Map<String, TaxonName> taxonNameMap = partitioner.getObjectMap(BerlinModelTaxonNameImport.NAMESPACE);
141
		Map<String, Reference> refMap = partitioner.getObjectMap(BerlinModelReferenceImport.REFERENCE_NAMESPACE);
142

    
143
		ResultSet rs = partitioner.getResultSet();
144
		try{
145
			boolean publishFlagExists = state.getConfig().getSource().checkColumnExists("PTaxon", "PublishFlag");
146
			boolean isEuroMed = isEuroMed(state.getConfig());
147
			while (rs.next()){
148

    
149
			//	if ((i++ % modCount) == 0 && i!= 1 ){ logger.info("PTaxa handled: " + (i-1));}
150

    
151
				//create TaxonName element
152
				int taxonId = rs.getInt("RIdentifier");
153
				int statusFk = rs.getInt("statusFk");
154

    
155
				int nameFk = rs.getInt("PTNameFk");
156
				int refFkInt = rs.getInt("PTRefFk");
157
				String doubtful = rs.getString("DoubtfulFlag");
158
				String uuid = null;
159
				if (resultSetHasColumn(rs,"UUID")){
160
					uuid = rs.getString("UUID");
161
				}
162

    
163
				TaxonName taxonName = null;
164
				taxonName  = taxonNameMap.get(String.valueOf(nameFk));
165

    
166
				Reference reference = null;
167
				String refFk = String.valueOf(refFkInt);
168
				reference = refMap.get(refFk);
169

    
170
				if(! config.isIgnoreNull()){
171
					if (taxonName == null ){
172
						logger.warn("TaxonName belonging to taxon (RIdentifier = " + taxonId + ") could not be found in store. Taxon will not be imported");
173
						success = false;
174
						continue; //next taxon
175
					}else if (reference == null ){
176
						logger.warn("Reference belonging to taxon could not be found in store. Taxon will not be imported");
177
						success = false;
178
						continue; //next taxon
179
					}
180
				}
181
				TaxonBase<?> taxonBase;
182
				Synonym synonym;
183
				Taxon taxon;
184
				try {
185
					logger.debug(statusFk);
186
					if (statusFk == T_STATUS_ACCEPTED || statusFk == T_STATUS_UNRESOLVED ){
187
						taxon = Taxon.NewInstance(taxonName, reference);
188
						taxonBase = taxon;
189
						if (statusFk == T_STATUS_UNRESOLVED){
190
							taxon.setTaxonStatusUnknown(true);
191
						}
192
					}else if (statusFk == T_STATUS_SYNONYM || statusFk == T_STATUS_PRO_PARTE_SYN || statusFk == T_STATUS_PARTIAL_SYN){
193
						synonym = Synonym.NewInstance(taxonName, reference);
194
						taxonBase = synonym;
195
						if (statusFk == T_STATUS_PRO_PARTE_SYN){
196
						    synonym.setProParte(true);
197
						}
198
						if (statusFk == T_STATUS_PARTIAL_SYN){
199
							synonym.setPartial(true);
200
						}
201
					}else{
202
						logger.warn("TaxonStatus " + statusFk + " not yet implemented. Taxon (RIdentifier = " + taxonId + ") left out.");
203
						success = false;
204
						continue;
205
					}
206
					if (uuid != null){
207
						taxonBase.setUuid(UUID.fromString(uuid));
208
					}
209

    
210
					//doubtful
211
					if (doubtful.equals("a")){
212
						taxonBase.setDoubtful(false);
213
					}else if(doubtful.equals("d")){
214
						taxonBase.setDoubtful(true);
215
					}else if(doubtful.equals("i")){
216
						taxonBase.setDoubtful(false);
217
						logger.warn("Doubtful = i (inactivated) does not exist in CDM. Doubtful set to false. RIdentifier: " + taxonId);
218
					}
219

    
220
					//detail
221
					String detail = rs.getString("Detail");
222
					if (isNotBlank(detail)){
223
						ExtensionType detailExtensionType = getExtensionType(state, BerlinModelTransformer.DETAIL_EXT_UUID, "micro reference","micro reference","micro ref.");
224
						Extension.NewInstance(taxonBase, detail, detailExtensionType);
225
					}
226
					//idInSource
227
					String idInSource = rs.getString("IdInSource");
228
					if (isNotBlank(idInSource)){
229
						ExtensionType detailExtensionType = getExtensionType(state, BerlinModelTransformer.ID_IN_SOURCE_EXT_UUID, "Berlin Model IdInSource","Berlin Model IdInSource","BM source id");
230
						Extension.NewInstance(taxonBase, idInSource, detailExtensionType);
231
					}
232
					//namePhrase
233
					String namePhrase = rs.getString("NamePhrase");
234
					if (StringUtils.isNotBlank(namePhrase)){
235
						taxonBase.setAppendedPhrase(namePhrase);
236
					}
237
					//useNameCache
238
					Boolean useNameCacheFlag = rs.getBoolean("UseNameCacheFlag");
239
					if (useNameCacheFlag){
240
						taxonBase.setUseNameCache(true);
241
					}
242
					//publisheFlag
243
					if (publishFlagExists){
244
						Boolean publishFlag = rs.getBoolean("PublishFlag");
245
						Boolean misapplied = false;
246
						if (isEuroMed){
247
							misapplied = rs.getBoolean("MA");
248
						}
249

    
250
						if ( ! misapplied){
251
							taxonBase.setPublish(publishFlag);
252
						}
253
					}
254

    
255
					//
256
					if (resultSetHasColumn(rs, "LastScrutiny")){
257
						String lastScrutiny = rs.getString("LastScrutiny");
258
						//TODO strange, why not Extension last scrutiny? To match PESI? Is there a difference
259
						//to LastScrutinyFK and SpeciesExpertFK?
260
						if (isNotBlank(lastScrutiny)){
261
						    ExtensionType extensionTypeSpeciesExpert = getExtensionType(state, BerlinModelTransformer.uuidSpeciesExpertName, "Species Expert", "Species Expert", "Species Expert");
262
						    taxonBase.addExtension(lastScrutiny, extensionTypeSpeciesExpert);
263
						    ExtensionType extensionTypeExpert = getExtensionType(state, BerlinModelTransformer.uuidExpertName, "Expert", "Expert for a taxonomic group", "Expert");
264
						    taxonBase.addExtension(lastScrutiny, extensionTypeExpert);
265
						}
266
					}
267
					//
268
					if (resultSetHasColumn(rs, "IsExcludedMarker")){
269
					    boolean isExcluded = rs.getBoolean("IsExcludedMarker");
270
					    if (isExcluded){
271
					        String extension = rs.getString("IsExcludedExtension");
272
					        String valueless = "not accepted: taxonomically valueless local or singular biotype";
273
					        String provisional = "provisional: probably a taxonomically valueless local or singular biotype";
274

    
275
					        MarkerType markerType = null;
276
					        if (valueless.equals(extension)){
277
					            markerType = getMarkerType(state, BerlinModelTransformer.uuidTaxonomicallyValueless, "taxonomically valueless", valueless, "valueless");
278
					        }else if (provisional.equals(extension)){
279
                                markerType = getMarkerType(state, BerlinModelTransformer.uuidProbablyTaxonomicallyValueless, "probably taxonomically valueless", provisional, "provisional");
280
                            }
281
					        if (markerType != null){
282
					            taxonBase.addMarker(Marker.NewInstance(markerType, true));
283
					        }else{
284
					            logger.warn("IsExcludedExtension not regonized for taxon " + taxonId + "; " + extension);
285
					        }
286
					    }
287
					}
288

    
289
					//Notes
290
					boolean excludeNotes = state.getConfig().isTaxonNoteAsFeature() && taxonBase.isInstanceOf(Taxon.class);
291
					doIdCreatedUpdatedNotes(state, taxonBase, rs, taxonId, NAMESPACE, false, excludeNotes);
292
					if (excludeNotes){
293
					    makeTaxonomicNote(state, CdmBase.deproxy(taxonBase, Taxon.class), rs.getString("Notes"));
294
					}
295

    
296
					//external url
297
					if (config.getMakeUrlForTaxon() != null){
298
						Method urlMethod = config.getMakeUrlForTaxon();
299
						urlMethod.invoke(null, taxonBase, rs);
300
					}
301

    
302
					partitioner.startDoSave();
303
					taxaToSave.add(taxonBase);
304
				} catch (Exception e) {
305
					logger.warn("An exception (" +e.getMessage()+") occurred when creating taxon with id " + taxonId + ". Taxon could not be saved.");
306
					success = false;
307
				}
308
			}
309
		} catch (DatabaseTypeNotSupportedException e) {
310
			logger.error("MethodNotSupportedException:" +  e);
311
			return false;
312
		} catch (Exception e) {
313
			logger.error("SQLException:" +  e);
314
			return false;
315
		}
316

    
317

    
318
		//	logger.info( i + " names handled");
319
		getTaxonService().save(taxaToSave);
320
		return success;
321
	}
322

    
323
	/**
324
     * @param state
325
     * @param taxonBase
326
	 * @param notes
327
     */
328
    private void makeTaxonomicNote(BerlinModelImportState state, Taxon taxon, String notes) {
329
        if (isNotBlank(notes)){
330
            TaxonDescription desc = getTaxonDescription(taxon, false, true);
331
            desc.setDefault(true);  //hard coded for Salvador, not used elsewhere as far as I can see
332
            TextData textData = TextData.NewInstance(Feature.NOTES() , notes, Language.SPANISH_CASTILIAN(), null);
333
            desc.addElement(textData);
334
        }
335
    }
336

    
337
    @Override
338
	public Map<Object, Map<String, ? extends CdmBase>> getRelatedObjectsForPartition(ResultSet rs, BerlinModelImportState state) {
339
		String nameSpace;
340
		Class<?> cdmClass;
341
		Set<String> idSet;
342
		Map<Object, Map<String, ? extends CdmBase>> result = new HashMap<>();
343

    
344
		try{
345
			Set<String> nameIdSet = new HashSet<>();
346
			Set<String> referenceIdSet = new HashSet<>();
347
			while (rs.next()){
348
				handleForeignKey(rs, nameIdSet, "PTNameFk");
349
				handleForeignKey(rs, referenceIdSet, "PTRefFk");
350
			}
351

    
352
			//name map
353
			nameSpace = BerlinModelTaxonNameImport.NAMESPACE;
354
			cdmClass = TaxonName.class;
355
			idSet = nameIdSet;
356
			Map<String, Person> nameMap = (Map<String, Person>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
357
			result.put(nameSpace, nameMap);
358

    
359
			//reference map
360
			nameSpace = BerlinModelReferenceImport.REFERENCE_NAMESPACE;
361
			cdmClass = Reference.class;
362
			idSet = referenceIdSet;
363
			Map<String, Reference> referenceMap = (Map<String, Reference>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
364
			result.put(nameSpace, referenceMap);
365

    
366
		} catch (SQLException e) {
367
			throw new RuntimeException(e);
368
		}
369
		return result;
370
	}
371

    
372
	@Override
373
	protected String getTableName() {
374
		return dbTableName;
375
	}
376

    
377
	@Override
378
	public String getPluralString() {
379
		return pluralString;
380
	}
381

    
382
	@Override
383
	protected boolean isIgnore(BerlinModelImportState state){
384
		return ! state.getConfig().isDoTaxa();
385
	}
386

    
387

    
388

    
389
}
(14-14/21)