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

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

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

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

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

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

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

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

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

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

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

    
470

    
471

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

    
540

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