Project

General

Profile

Download (21.8 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

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

    
27
import eu.etaxonomy.cdm.common.CdmUtils;
28
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
29
import eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer;
30
import eu.etaxonomy.cdm.io.berlinModel.in.validation.BerlinModelOccurrenceImportValidator;
31
import eu.etaxonomy.cdm.io.common.IOValidator;
32
import eu.etaxonomy.cdm.io.common.ResultSetPartitioner;
33
import eu.etaxonomy.cdm.io.common.Source;
34
import eu.etaxonomy.cdm.io.common.TdwgAreaProvider;
35
import eu.etaxonomy.cdm.model.common.Annotation;
36
import eu.etaxonomy.cdm.model.common.AnnotationType;
37
import eu.etaxonomy.cdm.model.common.CdmBase;
38
import eu.etaxonomy.cdm.model.common.ExtensionType;
39
import eu.etaxonomy.cdm.model.common.Language;
40
import eu.etaxonomy.cdm.model.common.Marker;
41
import eu.etaxonomy.cdm.model.common.MarkerType;
42
import eu.etaxonomy.cdm.model.common.OriginalSourceType;
43
import eu.etaxonomy.cdm.model.common.TermType;
44
import eu.etaxonomy.cdm.model.common.TermVocabulary;
45
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
46
import eu.etaxonomy.cdm.model.description.Distribution;
47
import eu.etaxonomy.cdm.model.description.PresenceAbsenceTermBase;
48
import eu.etaxonomy.cdm.model.description.TaxonDescription;
49
import eu.etaxonomy.cdm.model.location.NamedArea;
50
import eu.etaxonomy.cdm.model.location.NamedAreaLevel;
51
import eu.etaxonomy.cdm.model.location.NamedAreaType;
52
import eu.etaxonomy.cdm.model.reference.Reference;
53
import eu.etaxonomy.cdm.model.taxon.Taxon;
54
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
55
import eu.etaxonomy.cdm.strategy.exceptions.UnknownCdmTypeException;
56

    
57

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

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

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

    
75

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

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

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

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

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

    
273
	private String nullSafeTrim(String string) {
274
		if (string == null){
275
			return null;
276
		}else{
277
			return string.trim();
278
		}
279
	}
280

    
281
	/**
282
	 * 
283
	 */
284
	private TermVocabulary<NamedArea> makeEmptyEuroMedVocabulary() {
285
		TermType type = TermType.NamedArea;
286
		String description = "Euro+Med area vocabulary";
287
		String label = "E+M areas";
288
		String abbrev = null;
289
		URI termSourceUri = null;
290
		TermVocabulary<NamedArea> result = TermVocabulary.NewInstance(type, description, label, abbrev, termSourceUri);
291
		getVocabularyService().save(result);
292
		return result;
293
	}
294

    
295
	@Override
296
	public boolean doPartition(ResultSetPartitioner partitioner, BerlinModelImportState state) {
297
		boolean success = true;
298
		Set<TaxonBase> taxaToSave = new HashSet<TaxonBase>();
299
		
300
		Map<String, TaxonBase<?>> taxonMap = (Map<String, TaxonBase<?>>) partitioner.getObjectMap(BerlinModelTaxonImport.NAMESPACE);
301
			
302
		ResultSet rs = partitioner.getResultSet();
303

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

    
382
			logger.info("Taxa to save: " + taxaToSave.size());
383
			getTaxonService().save(taxaToSave);	
384
			
385
			return success;
386
		} catch (SQLException e) {
387
			logger.error("SQLException:" +  e);
388
			return false;
389
		}
390
	}
391

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

    
445
	@Override
446
	public Map<Object, Map<String, ? extends CdmBase>> getRelatedObjectsForPartition(ResultSet rs, BerlinModelImportState state) {
447
		String nameSpace;
448
		Class<?> cdmClass;
449
		Set<String> idSet;
450
		Map<Object, Map<String, ? extends CdmBase>> result = new HashMap<Object, Map<String, ? extends CdmBase>>();
451
		
452
		try{
453
			Set<String> taxonIdSet = new HashSet<String>();
454
			while (rs.next()){
455
				handleForeignKey(rs, taxonIdSet, "taxonId");
456
			}
457
			
458
			//taxon map
459
			nameSpace = BerlinModelTaxonImport.NAMESPACE;
460
			cdmClass = TaxonBase.class;
461
			idSet = taxonIdSet;
462
			Map<String, TaxonBase> objectMap = (Map<String, TaxonBase>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
463
			result.put(nameSpace, objectMap);
464

    
465
		} catch (SQLException e) {
466
			throw new RuntimeException(e);
467
		}
468
		return result;
469
	}
470

    
471

    
472

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

    
541

    
542
	@Override
543
	protected boolean isIgnore(BerlinModelImportState state){
544
		if (! state.getConfig().isDoOccurrence()){
545
			return true;
546
		}else{
547
			if (!this.checkSqlServerColumnExists(state.getConfig().getSource(), "emOccurrence", "OccurrenceId")){
548
				logger.error("emOccurrence table or emOccurrenceId does not exist. Must ignore occurrence import");
549
				return true;
550
			}else{
551
				return false;
552
			}
553
		}
554
	}
555
	
556
}
(10-10/21)