Project

General

Profile

Download (22.1 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 java.net.URI;
13
import java.sql.ResultSet;
14
import java.sql.SQLException;
15
import java.util.ArrayList;
16
import java.util.HashMap;
17
import java.util.HashSet;
18
import java.util.List;
19
import java.util.Map;
20
import java.util.Set;
21
import java.util.UUID;
22

    
23
import org.apache.commons.lang.StringUtils;
24
import org.apache.log4j.Logger;
25
import org.springframework.stereotype.Component;
26
import org.springframework.transaction.TransactionStatus;
27

    
28
import eu.etaxonomy.cdm.common.CdmUtils;
29
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
30
import eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer;
31
import eu.etaxonomy.cdm.io.berlinModel.in.validation.BerlinModelOccurrenceImportValidator;
32
import eu.etaxonomy.cdm.io.common.IOValidator;
33
import eu.etaxonomy.cdm.io.common.ResultSetPartitioner;
34
import eu.etaxonomy.cdm.io.common.Source;
35
import eu.etaxonomy.cdm.io.common.TdwgAreaProvider;
36
import eu.etaxonomy.cdm.model.common.Annotation;
37
import eu.etaxonomy.cdm.model.common.AnnotationType;
38
import eu.etaxonomy.cdm.model.common.CdmBase;
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.common.OriginalSourceType;
44
import eu.etaxonomy.cdm.model.common.TermType;
45
import eu.etaxonomy.cdm.model.common.TermVocabulary;
46
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
47
import eu.etaxonomy.cdm.model.description.Distribution;
48
import eu.etaxonomy.cdm.model.description.PresenceAbsenceTermBase;
49
import eu.etaxonomy.cdm.model.description.TaxonDescription;
50
import eu.etaxonomy.cdm.model.location.NamedArea;
51
import eu.etaxonomy.cdm.model.location.NamedAreaLevel;
52
import eu.etaxonomy.cdm.model.location.NamedAreaType;
53
import eu.etaxonomy.cdm.model.reference.Reference;
54
import eu.etaxonomy.cdm.model.taxon.Taxon;
55
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
56
import eu.etaxonomy.cdm.strategy.exceptions.UnknownCdmTypeException;
57

    
58

    
59
/**
60
 * @author a.mueller
61
 * @created 20.03.2008
62
 */
63
@Component
64
public class BerlinModelOccurrenceImport  extends BerlinModelImportBase {
65
	private static final String EM_AREA_NAMESPACE = "emArea";
66

    
67
	private static final Logger logger = Logger.getLogger(BerlinModelOccurrenceImport.class);
68

    
69
	public static final String NAMESPACE = "Occurrence";
70
	
71
	
72
	private static int modCount = 5000;
73
	private static final String pluralString = "occurrences";
74
	private static final String dbTableName = "emOccurrence";  //??
75

    
76

    
77
	public BerlinModelOccurrenceImport(){
78
		super(dbTableName, pluralString);
79
	}
80
	
81
	@Override
82
	protected String getIdQuery(BerlinModelImportState state) {
83
		String result = " SELECT occurrenceId FROM " + getTableName();
84
		if (StringUtils.isNotBlank(state.getConfig().getOccurrenceFilter())){
85
			result += " WHERE " +  state.getConfig().getOccurrenceFilter(); 
86
		} 
87
		return result;
88
	}
89

    
90
	@Override
91
	protected String getRecordQuery(BerlinModelImportConfigurator config) {
92
			String emCode = config.isIncludesAreaEmCode()? ", emArea.EMCode" : "";
93
			String strQuery =   //DISTINCT because otherwise emOccurrenceSource creates multiple records for a single distribution 
94
            " SELECT DISTINCT PTaxon.RIdentifier AS taxonId, emOccurrence.OccurrenceId, emOccurrence.Native, emOccurrence.Introduced, " +
95
            		" emOccurrence.Cultivated, emOccurSumCat.emOccurSumCatId, emOccurSumCat.Short, emOccurSumCat.Description, " +  
96
                	" emOccurSumCat.OutputCode, emArea.AreaId, emArea.TDWGCode " + emCode + 
97
                " FROM emOccurrence INNER JOIN " +  
98
                	" emArea ON emOccurrence.AreaFk = emArea.AreaId INNER JOIN " + 
99
                	" PTaxon ON emOccurrence.PTNameFk = PTaxon.PTNameFk AND emOccurrence.PTRefFk = PTaxon.PTRefFk LEFT OUTER JOIN " + 
100
                	" emOccurSumCat ON emOccurrence.SummaryStatus = emOccurSumCat.emOccurSumCatId LEFT OUTER JOIN " +  
101
                	" emOccurrenceSource ON emOccurrence.OccurrenceId = emOccurrenceSource.OccurrenceFk " +  
102
            " WHERE (emOccurrence.OccurrenceId IN (" + ID_LIST_TOKEN + ")  )" +  
103
                " ORDER BY PTaxon.RIdentifier";
104
		return strQuery;
105
	}
106

    
107
	private Map<Integer, NamedArea> euroMedAreas = new HashMap<Integer, NamedArea>();
108
	
109
	
110
	@Override
111
	public void doInvoke(BerlinModelImportState state) {
112
		if (state.getConfig().isUseEmAreaVocabulary()){
113
			try {
114
				createEuroMedAreas(state);
115
			} catch (Exception e) {
116
				logger.error("Exception occurred when trying to create euroMed Areas");
117
				e.printStackTrace();
118
				state.setSuccess(false);
119
			}
120
		}
121
		super.doInvoke(state);
122
		//reset
123
		euroMedAreas = new HashMap<Integer, NamedArea>();
124
	}
125
	
126
	private TermVocabulary<NamedArea> createEuroMedAreas(BerlinModelImportState state) throws SQLException {
127
		logger.warn("Start creating E+M areas");
128
		Source source = state.getConfig().getSource();
129
		Reference<?> sourceReference = state.getConfig().getSourceReference();
130
		
131
		TransactionStatus txStatus = this.startTransaction();
132
		
133
		sourceReference = getSourceReference(sourceReference);
134
		
135
		TermVocabulary<NamedArea> euroMedAreas = makeEmptyEuroMedVocabulary();
136
		
137
		MarkerType eurMarkerType = getMarkerType(state, BerlinModelTransformer.uuidEurArea, "eur", "eur Area", "eur");
138
		MarkerType euroMedAreaMarkerType = getMarkerType(state, BerlinModelTransformer.uuidEurMedArea, "EuroMedArea", "EuroMedArea", "EuroMedArea");
139
		ExtensionType isoCodeExtType = getExtensionType(state, BerlinModelTransformer.uuidIsoCode, "IsoCode", "IsoCode", "iso");
140
		ExtensionType tdwgCodeExtType = getExtensionType(state, BerlinModelTransformer.uuidTdwgAreaCode, "TDWG code", "TDWG Area code", "tdwg");
141
		ExtensionType mclCodeExtType = getExtensionType(state, BerlinModelTransformer.uuidMclCode, "MCL code", "MedCheckList code", "mcl");
142
		NamedAreaLevel areaLevelTop = getNamedAreaLevel(state, BerlinModelTransformer.uuidAreaLevelTop, "Euro+Med top area level", "Euro+Med top area level. This level is only to be used for the area representing the complete Euro+Med area", "e+m top", null);
143
		NamedAreaLevel areaLevelEm1 = getNamedAreaLevel(state, BerlinModelTransformer.uuidAreaLevelFirst, "Euro+Med 1. area level", "Euro+Med 1. area level", "e+m 1.", null);
144
		NamedAreaLevel areaLevelEm2 = getNamedAreaLevel(state, BerlinModelTransformer.uuidAreaLevelSecond, "Euro+Med 2. area level", "Euro+Med 2. area level", "Euro+Med 1. area level", null);
145
		
146
		
147
		String sql = "SELECT * , CASE WHEN EMCode = 'EM' THEN 'a' ELSE 'b' END as isEM " +
148
				" FROM emArea " +
149
				" ORDER BY isEM, EMCode"; 
150
		ResultSet rs = source.getResultSet(sql);
151
		
152
		NamedArea euroMedArea = null;
153
		NamedArea lastLevel2Area = null;
154
		
155
		//euroMedArea (EMCode = 'EM')
156
		rs.next();
157
		euroMedArea = makeSingleEuroMedArea(rs, eurMarkerType, euroMedAreaMarkerType, isoCodeExtType, tdwgCodeExtType, mclCodeExtType, 
158
				areaLevelTop, areaLevelEm1 , areaLevelEm2, sourceReference, euroMedArea, lastLevel2Area);
159
		euroMedAreas.addTerm(euroMedArea);
160
		
161
		//all other areas
162
		while (rs.next()){
163
			NamedArea newArea = makeSingleEuroMedArea(rs, eurMarkerType, euroMedAreaMarkerType,
164
					isoCodeExtType, tdwgCodeExtType, mclCodeExtType, 
165
					areaLevelTop, areaLevelEm1 , areaLevelEm2, sourceReference, euroMedArea, lastLevel2Area);
166
			euroMedAreas.addTerm(newArea);
167
			if (newArea.getPartOf().equals(euroMedArea)){
168
				lastLevel2Area = newArea;
169
			}
170
			getVocabularyService().saveOrUpdate(euroMedAreas);
171
		}	
172
		
173
		commitTransaction(txStatus);
174
		logger.warn("Created E+M areas");
175
		
176
		return euroMedAreas;
177
	}
178

    
179
	/**
180
	 * @param sourceReference
181
	 * @return
182
	 */
183
	private Reference<?> getSourceReference(Reference<?> sourceReference) {
184
		Reference<?> persistentSourceReference = getReferenceService().find(sourceReference.getUuid());  //just to be sure
185
		if (persistentSourceReference != null){
186
			sourceReference = persistentSourceReference;
187
		}
188
		return sourceReference;
189
	}
190

    
191
	/**
192
	 * @param eurMarkerType
193
	 * @param euroMedAreaMarkerType
194
	 * @param isoCodeExtType
195
	 * @param tdwgCodeExtType
196
	 * @param mclCodeExtType
197
	 * @param rs
198
	 * @param areaLevelEm2 
199
	 * @param areaLevelEm1 
200
	 * @param areaLevelTop 
201
	 * @throws SQLException
202
	 */
203
	private NamedArea makeSingleEuroMedArea(ResultSet rs, MarkerType eurMarkerType,
204
			MarkerType euroMedAreaMarkerType, ExtensionType isoCodeExtType,
205
			ExtensionType tdwgCodeExtType, ExtensionType mclCodeExtType,
206
			NamedAreaLevel areaLevelTop, NamedAreaLevel areaLevelEm1, NamedAreaLevel areaLevelEm2, 
207
			Reference<?> sourceReference, NamedArea euroMedArea, NamedArea level2Area) throws SQLException {
208
		Integer areaId = rs.getInt("AreaId");
209
		String emCode = nullSafeTrim(rs.getString("EMCode"));
210
		String isoCode = nullSafeTrim(rs.getString("ISOCode"));
211
		String tdwgCode = nullSafeTrim(rs.getString("TDWGCode"));
212
		String unit = nullSafeTrim(rs.getString("Unit"));
213
//				      ,[Status]
214
//				      ,[OutputOrder]
215
		boolean eurMarker = rs.getBoolean("eur");
216
		boolean euroMedAreaMarker = rs.getBoolean("EuroMedArea");
217
		String notes = nullSafeTrim(rs.getString("Notes"));
218
		String mclCode = nullSafeTrim(rs.getString("MCLCode"));
219
		String geoSearch = nullSafeTrim(rs.getString("NameForGeoSearch"));
220
		
221
		if (isBlank(emCode)){
222
			emCode = unit;
223
		}
224
		
225
		//uuid
226
		UUID uuid = BerlinModelTransformer.getEMAreaUuid(emCode);
227
		NamedArea area = (NamedArea)getTermService().find(uuid);
228
		if (area == null){
229
			//label
230
			area = NamedArea.NewInstance(geoSearch, unit, emCode);
231
			if (uuid != null){
232
				area.setUuid(uuid);
233
			}else{
234
				logger.warn("Uuuid for emCode could not be defined: " + emCode);
235
			}
236
		}
237
		
238
		
239
		//code
240
		area.setIdInVocabulary(emCode);
241
		//notes
242
		if (StringUtils.isNotEmpty(notes)){
243
			area.addAnnotation(Annotation.NewInstance(notes, AnnotationType.EDITORIAL(), Language.DEFAULT()));
244
		}
245
		//markers
246
		area.addMarker(Marker.NewInstance(eurMarkerType, eurMarker));
247
		area.addMarker(Marker.NewInstance(euroMedAreaMarkerType, euroMedAreaMarker));
248
		
249
		//extensions
250
		if (isNotBlank(isoCode)){
251
			area.addExtension(isoCode, isoCodeExtType);
252
		}
253
		if (isNotBlank(tdwgCode)){
254
			area.addExtension(tdwgCode, tdwgCodeExtType);
255
		}
256
		if (isNotBlank(mclCode)){
257
			area.addExtension(mclCode, mclCodeExtType);
258
		}
259
		
260
		//type
261
		area.setType(NamedAreaType.ADMINISTRATION_AREA());
262
		
263
		//source
264
		area.addSource(OriginalSourceType.Import, String.valueOf(areaId), EM_AREA_NAMESPACE, sourceReference, null);
265
		
266
		//parent
267
		if (euroMedArea != null){
268
			if (emCode.contains("(")){
269
				area.setPartOf(level2Area);
270
				area.setLevel(areaLevelEm2);
271
			}else{
272
				area.setPartOf(euroMedArea);
273
				area.setLevel(areaLevelEm1);
274
			}
275
		}else{
276
			area.setLevel(areaLevelTop);
277
		}
278
		this.euroMedAreas.put(areaId, area);
279
		
280
		//save
281
		getTermService().saveOrUpdate(area);
282
		
283
		return area;
284
	}
285

    
286
	private String nullSafeTrim(String string) {
287
		if (string == null){
288
			return null;
289
		}else{
290
			return string.trim();
291
		}
292
	}
293

    
294
	/**
295
	 * 
296
	 */
297
	private TermVocabulary<NamedArea> makeEmptyEuroMedVocabulary() {
298
		TermType type = TermType.NamedArea;
299
		String description = "Euro+Med area vocabulary";
300
		String label = "E+M areas";
301
		String abbrev = null;
302
		URI termSourceUri = null;
303
		TermVocabulary<NamedArea> result = TermVocabulary.NewInstance(type, description, label, abbrev, termSourceUri);
304
		getVocabularyService().save(result);
305
		return result;
306
	}
307

    
308
	@Override
309
	public boolean doPartition(ResultSetPartitioner partitioner, BerlinModelImportState state) {
310
		boolean success = true;
311
		Set<TaxonBase> taxaToSave = new HashSet<TaxonBase>();
312
		
313
		Map<String, TaxonBase<?>> taxonMap = (Map<String, TaxonBase<?>>) partitioner.getObjectMap(BerlinModelTaxonImport.NAMESPACE);
314
			
315
		ResultSet rs = partitioner.getResultSet();
316

    
317
		try {
318
			//map to store the mapping of duplicate berlin model occurrences to their real distributions
319
			//duplicated may occurr due to area mappings from BM areas to TDWG areas
320
			Map<Integer, String> duplicateMap = new HashMap<Integer, String>();
321
			int oldTaxonId = -1;
322
			TaxonDescription oldDescription = null;
323
			int i = 0;
324
			int countDescriptions = 0;
325
			int countDistributions = 0;
326
			int countDuplicates = 0;
327
			//for each reference
328
            while (rs.next()){
329
                
330
            	if ((i++ % modCount) == 0 && i!= 1 ){ logger.info("Facts handled: " + (i-1));}
331
                
332
                int occurrenceId = rs.getInt("OccurrenceId");
333
                int newTaxonId = rs.getInt("taxonId");
334
                
335
                Integer emStatusId = nullSafeInt(rs, "emOccurSumCatId");
336
                
337
                try {
338
                	//status
339
                	PresenceAbsenceTermBase<?> status = null;
340
                	String alternativeStatusString = null;
341
					if (emStatusId != null){
342
						status = BerlinModelTransformer.occStatus2PresenceAbsence(emStatusId);
343
					}else{
344
						String[] stringArray = new String[]{rs.getString("Native"), rs.getString("Introduced"), rs.getString("Cultivated")};
345
						alternativeStatusString = CdmUtils.concat(",", stringArray);
346
					}
347
                     
348
					Reference<?> sourceRef = state.getTransactionalSourceReference();
349
                    
350
					List<NamedArea> areas = makeAreaList(state, rs,	occurrenceId);
351
                     
352
                     //create description(elements)
353
                     TaxonDescription taxonDescription = getTaxonDescription(newTaxonId, oldTaxonId, oldDescription, taxonMap, occurrenceId, sourceRef);
354
                     for (NamedArea area : areas){
355
                           Distribution distribution = Distribution.NewInstance(area, status);
356
                           if (status == null){
357
                        	   AnnotationType annotationType = AnnotationType.EDITORIAL();
358
                        	   Annotation annotation = Annotation.NewInstance(alternativeStatusString, annotationType, null);
359
                        	   distribution.addAnnotation(annotation);
360
                        	   distribution.addMarker(Marker.NewInstance(MarkerType.PUBLISH(), false));
361
                           }
362
//                         distribution.setCitation(sourceRef);
363
                           if (taxonDescription != null) { 
364
                        	   Distribution duplicate = checkIsNoDuplicate(taxonDescription, distribution, duplicateMap , occurrenceId);
365
                               if (duplicate == null){
366
	                        	   taxonDescription.addElement(distribution); 
367
	                               distribution.addImportSource(String.valueOf(occurrenceId), NAMESPACE, state.getTransactionalSourceReference(), null);
368
	                        	   countDistributions++; 
369
	                               if (taxonDescription != oldDescription){ 
370
	                            	   taxaToSave.add(taxonDescription.getTaxon()); 
371
	                                   oldDescription = taxonDescription; 
372
	                                   countDescriptions++; 
373
	                               	} 
374
                               }else{                          	  
375
                            	   countDuplicates++;
376
                            	   duplicate.addImportSource(String.valueOf(occurrenceId), NAMESPACE, state.getTransactionalSourceReference(), null);
377
                            	   logger.info("Distribution is duplicate");	                           }
378
	                       	} else { 
379
	                       		logger.warn("Distribution " + area.getLabel() + " ignored. OccurrenceId = " + occurrenceId);
380
	                       		success = false;
381
	                       	}
382
                     }
383
                     
384
                } catch (UnknownCdmTypeException e) {
385
                     logger.error("Unknown presenceAbsence status id: " + emStatusId); 
386
                	e.printStackTrace();
387
                     success = false;
388
                }
389
                
390
            }
391
           
392
            logger.info("Distributions: " + countDistributions + ", Descriptions: " + countDescriptions );
393
			logger.info("Duplicate occurrences: "  + (countDuplicates));
394

    
395
			logger.info("Taxa to save: " + taxaToSave.size());
396
			getTaxonService().save(taxaToSave);	
397
			
398
			return success;
399
		} catch (SQLException e) {
400
			logger.error("SQLException:" +  e);
401
			return false;
402
		}
403
	}
404

    
405
	/**
406
	 * @param state
407
	 * @param rs
408
	 * @param occurrenceId
409
	 * @param tdwgCodeString
410
	 * @param emCodeString
411
	 * @return
412
	 * @throws SQLException
413
	 */
414
	//Create area list
415
	private List<NamedArea> makeAreaList(BerlinModelImportState state, ResultSet rs, int occurrenceId) throws SQLException {
416
		List<NamedArea> areas = new ArrayList<NamedArea>();
417
		
418
		if (state.getConfig().isUseEmAreaVocabulary()){
419
			Integer areaId = rs.getInt("AreaId");
420
	        NamedArea area = this.euroMedAreas.get(areaId);
421
			areas.add(area);
422
		}else{
423
	        String tdwgCodeString = rs.getString("TDWGCode");
424
	        String emCodeString = state.getConfig().isIncludesAreaEmCode() ? rs.getString("EMCode") : null;
425
	
426
			if (tdwgCodeString != null){
427
			
428
				String[] tdwgCodes = new String[]{tdwgCodeString};
429
				if (state.getConfig().isSplitTdwgCodes()){
430
					tdwgCodes = tdwgCodeString.split(";");
431
				}
432
				
433
				for (String tdwgCode : tdwgCodes){
434
					NamedArea area = TdwgAreaProvider.getAreaByTdwgAbbreviation(tdwgCode.trim());
435
			    	if (area == null){
436
			    		area = getOtherAreas(state, emCodeString, tdwgCodeString);
437
			    	}
438
			    	if (area != null){
439
			    		areas.add(area);
440
			    	}
441
				}
442
			 }
443
			
444
			 if (areas.size()== 0){
445
				 NamedArea area = getOtherAreas(state, emCodeString, tdwgCodeString);
446
				 if (area != null){
447
			         areas.add(area);
448
			   }
449
			 }
450
			 if (areas.size() == 0){
451
				 String areaId = rs.getString("AreaId");
452
				 logger.warn("No areas defined for occurrence " + occurrenceId + ". EMCode: " + CdmUtils.Nz(emCodeString).trim() + ". AreaId: " + areaId );
453
			 }
454
		}
455
		return areas;
456
	}
457

    
458
	@Override
459
	public Map<Object, Map<String, ? extends CdmBase>> getRelatedObjectsForPartition(ResultSet rs, BerlinModelImportState state) {
460
		String nameSpace;
461
		Class<?> cdmClass;
462
		Set<String> idSet;
463
		Map<Object, Map<String, ? extends CdmBase>> result = new HashMap<Object, Map<String, ? extends CdmBase>>();
464
		
465
		try{
466
			Set<String> taxonIdSet = new HashSet<String>();
467
			while (rs.next()){
468
				handleForeignKey(rs, taxonIdSet, "taxonId");
469
			}
470
			
471
			//taxon map
472
			nameSpace = BerlinModelTaxonImport.NAMESPACE;
473
			cdmClass = TaxonBase.class;
474
			idSet = taxonIdSet;
475
			Map<String, TaxonBase> objectMap = (Map<String, TaxonBase>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
476
			result.put(nameSpace, objectMap);
477

    
478
		} catch (SQLException e) {
479
			throw new RuntimeException(e);
480
		}
481
		return result;
482
	}
483

    
484

    
485

    
486
	/**
487
     * Tests if a distribution with the same tdwgArea and the same status already exists in the description. 
488
     * If so the old distribution is returned 
489
     * @param description
490
     * @param tdwgArea
491
     * @return false, if dupplicate exists. True otherwise.
492
     */
493
    private Distribution checkIsNoDuplicate(TaxonDescription description, Distribution distribution, Map<Integer, String> duplicateMap, Integer bmDistributionId){
494
    	for (DescriptionElementBase descElBase : description.getElements()){
495
    		if (descElBase.isInstanceOf(Distribution.class)){
496
    			Distribution oldDistr = HibernateProxyHelper.deproxy(descElBase, Distribution.class);
497
    			NamedArea oldArea = oldDistr.getArea();
498
    			if (oldArea != null && oldArea.equals(distribution.getArea())){
499
    				PresenceAbsenceTermBase<?> oldStatus = oldDistr.getStatus();
500
    				if (oldStatus != null && oldStatus.equals(distribution.getStatus())){
501
    					duplicateMap.put(bmDistributionId, oldDistr.getSources().iterator().next().getIdInSource());
502
    					return oldDistr;
503
    				}
504
    			}
505
    		}
506
    	}
507
    	return null;
508
    }
509
	
510
	/**
511
	 * Use same TaxonDescription if two records belong to the same taxon 
512
	 * @param newTaxonId
513
	 * @param oldTaxonId
514
	 * @param oldDescription
515
	 * @param taxonMap
516
	 * @return
517
	 */
518
	private TaxonDescription getTaxonDescription(int newTaxonId, int oldTaxonId, TaxonDescription oldDescription, Map<String, TaxonBase<?>> taxonMap, int occurrenceId, Reference<?> sourceSec){
519
		TaxonDescription result = null;
520
		if (oldDescription == null || newTaxonId != oldTaxonId){
521
			TaxonBase<?> taxonBase = taxonMap.get(String.valueOf(newTaxonId));
522
			//TODO for testing
523
			//TaxonBase taxonBase = Taxon.NewInstance(BotanicalName.NewInstance(Rank.SPECIES()), null);
524
			Taxon taxon;
525
			if ( taxonBase instanceof Taxon ) {
526
				taxon = (Taxon) taxonBase;
527
			} else if (taxonBase != null) {
528
				logger.warn("TaxonBase for Occurrence " + occurrenceId + " was not of type Taxon but: " + taxonBase.getClass().getSimpleName());
529
				return null;
530
			} else {
531
				logger.warn("TaxonBase for Occurrence " + occurrenceId + " is null.");
532
				return null;
533
			}		
534
			Set<TaxonDescription> descriptionSet= taxon.getDescriptions();
535
			if (descriptionSet.size() > 0) {
536
				result = descriptionSet.iterator().next(); 
537
			}else{
538
				result = TaxonDescription.NewInstance();
539
				result.setTitleCache(sourceSec.getTitleCache(), true);
540
				taxon.addDescription(result);
541
			}
542
		}else{
543
			result = oldDescription;
544
		}
545
		return result;
546
	}
547
	
548
	@Override
549
	protected boolean doCheck(BerlinModelImportState state){
550
		IOValidator<BerlinModelImportState> validator = new BerlinModelOccurrenceImportValidator();
551
		return validator.validate(state);
552
	}
553

    
554

    
555
	@Override
556
	protected boolean isIgnore(BerlinModelImportState state){
557
		if (! state.getConfig().isDoOccurrence()){
558
			return true;
559
		}else{
560
			if (!this.checkSqlServerColumnExists(state.getConfig().getSource(), "emOccurrence", "OccurrenceId")){
561
				logger.error("emOccurrence table or emOccurrenceId does not exist. Must ignore occurrence import");
562
				return true;
563
			}else{
564
				return false;
565
			}
566
		}
567
	}
568
	
569
}
(10-10/21)