Project

General

Profile

Download (15.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.algaterra;
11

    
12
import java.sql.Date;
13
import java.sql.ResultSet;
14
import java.sql.SQLException;
15
import java.util.HashMap;
16
import java.util.HashSet;
17
import java.util.Map;
18
import java.util.Set;
19

    
20
import org.apache.commons.lang.StringUtils;
21
import org.apache.log4j.Logger;
22
import org.springframework.stereotype.Component;
23

    
24
import eu.etaxonomy.cdm.api.facade.DerivedUnitFacade;
25
import eu.etaxonomy.cdm.api.facade.DerivedUnitFacade.DerivedUnitType;
26
import eu.etaxonomy.cdm.api.facade.DerivedUnitFacadeCacheStrategy;
27
import eu.etaxonomy.cdm.api.facade.DerivedUnitFacadeNotSupportedException;
28
import eu.etaxonomy.cdm.common.CdmUtils;
29
import eu.etaxonomy.cdm.io.algaterra.validation.AlgaTerraSpecimenImportValidator;
30
import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportConfigurator;
31
import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportState;
32
import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelReferenceImport;
33
import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelTaxonImport;
34
import eu.etaxonomy.cdm.io.common.IOValidator;
35
import eu.etaxonomy.cdm.io.common.ResultSetPartitioner;
36
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
37
import eu.etaxonomy.cdm.model.common.CdmBase;
38
import eu.etaxonomy.cdm.model.common.TimePeriod;
39
import eu.etaxonomy.cdm.model.description.Feature;
40
import eu.etaxonomy.cdm.model.description.IndividualsAssociation;
41
import eu.etaxonomy.cdm.model.description.TaxonDescription;
42
import eu.etaxonomy.cdm.model.occurrence.DerivationEvent;
43
import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
44
import eu.etaxonomy.cdm.model.occurrence.DerivedUnitBase;
45
import eu.etaxonomy.cdm.model.occurrence.DeterminationEvent;
46
import eu.etaxonomy.cdm.model.occurrence.FieldObservation;
47
import eu.etaxonomy.cdm.model.occurrence.Fossil;
48
import eu.etaxonomy.cdm.model.occurrence.LivingBeing;
49
import eu.etaxonomy.cdm.model.occurrence.Observation;
50
import eu.etaxonomy.cdm.model.occurrence.Specimen;
51
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
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

    
56

    
57
/**
58
 * Alga Terra Import für den Fact mit FactId =202 (Ecology)
59
 * @author a.mueller
60
 * @created 01.09.2012
61
 */
62
@Component
63
public class AlgaTerraFactEcologyImport  extends AlgaTerraSpecimenImportBase {
64
	private static final Logger logger = Logger.getLogger(AlgaTerraFactEcologyImport.class);
65

    
66
	
67
	private static int modCount = 5000;
68
	private static final String pluralString = "determinations";
69
	private static final String dbTableName = "Fact"; 
70

    
71

    
72
	public AlgaTerraFactEcologyImport(){
73
		super(dbTableName, pluralString);
74
	}
75
	
76
	
77
	
78
	/* (non-Javadoc)
79
	 * @see eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportBase#getIdQuery()
80
	 */
81
	@Override
82
	protected String getIdQuery(BerlinModelImportState state) {
83
		String result = " SELECT f.factId " + 
84
				" FROM Fact f LEFT JOIN PTaxon pt ON f.PTNameFk = pt.PTNameFk AND f.PTRefFk = pt.PTRefFk " 
85
				+ " WHERE f.FactCategoryFk = 202 "
86
				+ " ORDER BY pt.RIdentifier, f.FactId ";
87
		return result;
88
	}
89

    
90
	/* (non-Javadoc)
91
	 * @see eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportBase#getRecordQuery(eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportConfigurator)
92
	 */
93
	@Override
94
	protected String getRecordQuery(BerlinModelImportConfigurator config) {
95
			String strQuery =   
96
            " SELECT pt.RIdentifier as taxonId, f.* " + 
97
            " FROM Fact f " + 
98
                 " LEFT JOIN PTaxon pt ON f.PTNameFk =pt.PTNameFk AND f.PTRefFk = pt.PTRefFk " +
99
             " WHERE f.FactCategoryFk = 202 AND (f.FactId IN (" + ID_LIST_TOKEN + ")  )"  
100
            + " ORDER BY pt.RIdentifier, f.FactId "
101
            ;
102
		return strQuery;
103
	}
104

    
105
	/* (non-Javadoc)
106
	 * @see eu.etaxonomy.cdm.io.berlinModel.in.IPartitionedIO#doPartition(eu.etaxonomy.cdm.io.berlinModel.in.ResultSetPartitioner, eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportState)
107
	 */
108
	public boolean doPartition(ResultSetPartitioner partitioner, BerlinModelImportState bmState) {
109
		boolean success = true;
110
		
111
		AlgaTerraImportState state = (AlgaTerraImportState)bmState;
112
		Set<TaxonBase> taxaToSave = new HashSet<TaxonBase>();
113
		
114
		Map<String, TaxonBase> taxonMap = (Map<String, TaxonBase>) partitioner.getObjectMap(BerlinModelTaxonImport.NAMESPACE);
115
		Map<String, DerivedUnitBase> ecoFactDerivedUnitMap = (Map<String, DerivedUnitBase>) partitioner.getObjectMap(ECO_FACT_DERIVED_UNIT_NAMESPACE);
116
		
117
		ResultSet rs = partitioner.getResultSet();
118

    
119
		try {
120
			
121
			int i = 0;
122

    
123
			//for each reference
124
            while (rs.next()){
125
                
126
        		if ((i++ % modCount) == 0 && i!= 1 ){ logger.info(pluralString + " handled: " + (i-1));}
127
				
128
				Integer taxonId = nullSafeInt(rs, "taxonId");
129
				int factId = rs.getInt("FactId");
130
				Integer ecoFactId = nullSafeInt(rs, "ExtensionFk");
131
				String recordBasis = rs.getString("RecordBasis");
132
				
133
				
134
				try {
135
					
136
					//source ref
137
					Reference<?> sourceRef = state.getTransactionalSourceReference();
138
				
139
					DerivedUnitBase<?> ecoFact = ecoFactDerivedUnitMap.get(String.valueOf(ecoFactId));
140
					if (ecoFact == null){
141
						logger.warn("EcoFact is null for EcoFact: " + CdmUtils.Nz(ecoFactId) + ", taxonId: " + CdmUtils.Nz(taxonId));
142
					}
143
					
144
					//description element
145
					if (taxonId != null){
146
						Taxon taxon = getTaxon(state, taxonId, taxonMap, factId);		
147
						
148
						if(taxon != null){
149
							DerivedUnitBase identifiedSpecimen = makeIdentifiedSpecimen(ecoFact, recordBasis);
150
							
151
							makeDetermination(state, rs, taxon, identifiedSpecimen, factId, partitioner);
152
													
153
							makeIndividualsAssociation(state, taxon, sourceRef, identifiedSpecimen);
154
							
155
							this.doIdCreatedUpdatedNotes(state, identifiedSpecimen, rs, factId, getDerivedUnitNameSpace());
156

    
157
							identifiedSpecimen.setCacheStrategy(new DerivedUnitFacadeCacheStrategy());
158
							taxaToSave.add(taxon);
159
						}
160
					}else{
161
						logger.warn("No taxon defined for ecology fact: " +  factId);
162
					}
163
					
164

    
165
				} catch (Exception e) {
166
					logger.warn("Exception in FactEcology: FactId " + factId + ". " + e.getMessage());
167
					e.printStackTrace();
168
				} 
169
                
170
            }
171
           
172
//            logger.warn("Specimen: " + countSpecimen + ", Descriptions: " + countDescriptions );
173

    
174
			logger.warn("Taxa to save: " + taxaToSave.size());
175
			getTaxonService().save(taxaToSave);	
176
			
177
			return success;
178
		} catch (SQLException e) {
179
			logger.error("SQLException:" +  e);
180
			return false;
181
		}
182
	}
183
	
184
	private void makeIndividualsAssociation(AlgaTerraImportState state, Taxon taxon, Reference<?> sourceRef, DerivedUnitBase<?> identifiedSpecimen){
185
		TaxonDescription taxonDescription = getTaxonDescription(state, taxon, sourceRef);
186
		IndividualsAssociation indAssociation = IndividualsAssociation.NewInstance();
187
		Feature feature = makeFeature(identifiedSpecimen);
188
		indAssociation.setAssociatedSpecimenOrObservation(identifiedSpecimen);
189
		indAssociation.setFeature(feature);
190
		taxonDescription.addElement(indAssociation);	
191
	}
192
	
193
	private void makeDetermination(AlgaTerraImportState state, ResultSet rs, Taxon taxon, DerivedUnitBase<?> identifiedSpecimen, int factId, ResultSetPartitioner partitioner) throws SQLException {
194
		Date identifiedWhen = rs.getDate("IdentifiedWhen");
195
		Date identifiedWhenEnd = rs.getDate("IdentiedWhenEnd");
196
		boolean restrictedFlag = rs.getBoolean("RestrictedFlag");
197
		//Team FK ist immer null
198
		String identifiedBy = rs.getString("IdentifiedBy");
199
		String identificationReference = rs.getString("IdentificationReference");
200
		Integer refFk = nullSafeInt(rs, "IdentifidationRefFk");
201
		
202
		
203
		DeterminationEvent determination = DeterminationEvent.NewInstance(taxon, identifiedSpecimen);
204
		TimePeriod determinationPeriod = TimePeriod.NewInstance(identifiedWhen, identifiedWhenEnd);
205
		determination.setTimeperiod(determinationPeriod);
206
		determination.setPreferredFlag(! restrictedFlag);
207
		//TODO 
208
		
209
		TeamOrPersonBase<?> author = getAuthor(identifiedBy);
210
		determination.setDeterminer(author);
211
		if (refFk != null){
212
			Map<String, Reference> biblioRefMap = (Map<String, Reference>) partitioner.getObjectMap(BerlinModelReferenceImport.BIBLIO_REFERENCE_NAMESPACE);
213
			Map<String, Reference> nomRefMap = (Map<String, Reference>) partitioner.getObjectMap(BerlinModelReferenceImport.NOM_REFERENCE_NAMESPACE);
214
			
215
			Reference<?> ref = getReferenceOnlyFromMaps(biblioRefMap, nomRefMap, String.valueOf(refFk));
216
			determination.addReference(ref);
217
		}else{
218
			//IdentificationReference is not to be handled according to Henning
219
			if (StringUtils.isNotBlank(identificationReference)){
220
				logger.warn("IdentificationReference exists without IdentificationRefFk. FactId: "+  factId);
221
			}
222
		}
223
		
224
		
225
		
226
		//TODO
227
//		kind of identification, IdentificationUncertainty, IdentificationMethod, 
228
		
229
		
230
	}
231

    
232

    
233

    
234
	private DerivedUnitBase<?> makeIdentifiedSpecimen(DerivedUnitBase<?> ecoFact, String recordBasis) {
235
		//TODO event type
236
		DerivationEvent event = DerivationEvent.NewInstance();
237
		DerivedUnitType derivedUnitType = makeDerivedUnitType(recordBasis);
238
		if (derivedUnitType == null){
239
			logger.warn("NULL");
240
		}
241
		
242
		DerivedUnitBase<?> result = derivedUnitType.getNewDerivedUnitInstance();
243
		result.setDerivedFrom(event);
244
		ecoFact.addDerivationEvent(event);
245
		
246
		return result;
247
	}
248

    
249

    
250

    
251
	protected String getDerivedUnitNameSpace(){
252
		return FACT_ECOLOGY_NAMESPACE;
253
	}
254
	
255
	protected String getFieldObservationNameSpace(){
256
		return null;
257
	}
258

    
259

    
260

    
261

    
262
	/**
263
	 * @param state
264
	 * @param ecoFactId
265
	 * @param derivedUnitMap
266
	 * @param type 
267
	 * @return
268
	 */
269
	private DerivedUnitFacade getDerivedUnit(AlgaTerraImportState state, int ecoFactId, Map<String, DerivedUnit> derivedUnitMap, DerivedUnitType type) {
270
		String key = String.valueOf(ecoFactId);
271
		DerivedUnit derivedUnit = derivedUnitMap.get(key);
272
		DerivedUnitFacade facade;
273
		if (derivedUnit == null){
274
			facade = DerivedUnitFacade.NewInstance(type);
275
			derivedUnitMap.put(key, derivedUnit);
276
		}else{
277
			try {
278
				facade = DerivedUnitFacade.NewInstance(derivedUnit);
279
			} catch (DerivedUnitFacadeNotSupportedException e) {
280
				logger.error(e.getMessage());
281
				facade = DerivedUnitFacade.NewInstance(type);
282
			}
283
		}
284
		
285
		return facade;
286
	}
287
	
288
	private Feature makeFeature(SpecimenOrObservationBase unit) {
289
		if (unit.isInstanceOf(DerivedUnit.class)){
290
			return Feature.INDIVIDUALS_ASSOCIATION();
291
		}else if (unit.isInstanceOf(FieldObservation.class) || unit.isInstanceOf(Observation.class) ){
292
			return Feature.OBSERVATION();
293
		}else if (unit.isInstanceOf(Fossil.class) || unit.isInstanceOf(LivingBeing.class) || unit.isInstanceOf(Specimen.class )){
294
			return Feature.SPECIMEN();
295
		}
296
		logger.warn("No feature defined for derived unit class: " + unit.getClass().getSimpleName());
297
		return null;
298
	}
299

    
300

    
301
	private DerivedUnitType makeDerivedUnitType(String recordBasis) {
302
		DerivedUnitType result = null;
303
		if (StringUtils.isBlank(recordBasis)){
304
			result = DerivedUnitType.DerivedUnit;
305
		} else if (recordBasis.equalsIgnoreCase("FossileSpecimen")){
306
			result = DerivedUnitType.Fossil;
307
		}else if (recordBasis.equalsIgnoreCase("Observation")){
308
			result = DerivedUnitType.Observation;
309
		}else if (recordBasis.equalsIgnoreCase("HumanObservation")){
310
			result = DerivedUnitType.Observation;
311
		}else if (recordBasis.equalsIgnoreCase("Literature")){
312
			logger.warn("Literature record basis not yet supported");
313
			result = DerivedUnitType.DerivedUnit;
314
		}else if (recordBasis.equalsIgnoreCase("LivingSpecimen")){
315
			result = DerivedUnitType.LivingBeing;
316
		}else if (recordBasis.equalsIgnoreCase("LivingCulture")){
317
			logger.warn("LivingCulture record basis not yet supported");
318
			result = DerivedUnitType.DerivedUnit;
319
		}else if (recordBasis.equalsIgnoreCase("MachineObservation")){
320
			logger.warn("MachineObservation record basis not yet supported");
321
			result = DerivedUnitType.Observation;
322
		}else if (recordBasis.equalsIgnoreCase("PreservedSpecimen")){
323
			result = DerivedUnitType.Specimen;
324
		}
325
		return result;
326
	}
327

    
328

    
329

    
330
	/* (non-Javadoc)
331
	 * @see eu.etaxonomy.cdm.io.berlinModel.in.IPartitionedIO#getRelatedObjectsForPartition(java.sql.ResultSet)
332
	 */
333
	public Map<Object, Map<String, ? extends CdmBase>> getRelatedObjectsForPartition(ResultSet rs) {
334
		String nameSpace;
335
		Class cdmClass;
336
		Set<String> idSet;
337
		Map<Object, Map<String, ? extends CdmBase>> result = new HashMap<Object, Map<String, ? extends CdmBase>>();
338
		
339
		try{
340
			Set<String> taxonIdSet = new HashSet<String>();
341
			Set<String> extensionFkSet = new HashSet<String>();
342
			Set<String> referenceIdSet = new HashSet<String>();
343
			
344
			while (rs.next()){
345
				handleForeignKey(rs, taxonIdSet, "taxonId");
346
				handleForeignKey(rs, extensionFkSet, "extensionFk");
347
				handleForeignKey(rs, referenceIdSet, "IdentifidationRefFk");
348
			}
349
			
350
			//taxon map
351
			nameSpace = BerlinModelTaxonImport.NAMESPACE;
352
			cdmClass = TaxonBase.class;
353
			idSet = taxonIdSet;
354
			Map<String, TaxonBase> objectMap = (Map<String, TaxonBase>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
355
			result.put(nameSpace, objectMap);
356

    
357
			//derived unit map
358
			nameSpace = AlgaTerraFactEcologyImport.ECO_FACT_DERIVED_UNIT_NAMESPACE;
359
			cdmClass = DerivedUnitBase.class;
360
			idSet = extensionFkSet;
361
			Map<String, DerivedUnitBase> derivedUnitMap = (Map<String, DerivedUnitBase>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
362
			result.put(nameSpace, derivedUnitMap);
363

    
364
			//nom reference map
365
			nameSpace = BerlinModelReferenceImport.NOM_REFERENCE_NAMESPACE;
366
			cdmClass = Reference.class;
367
			idSet = referenceIdSet;
368
			Map<String, Reference> nomReferenceMap = (Map<String, Reference>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
369
			result.put(nameSpace, nomReferenceMap);
370

    
371
			//biblio reference map
372
			nameSpace = BerlinModelReferenceImport.BIBLIO_REFERENCE_NAMESPACE;
373
			cdmClass = Reference.class;
374
			idSet = referenceIdSet;
375
			Map<String, Reference> biblioReferenceMap = (Map<String, Reference>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
376
			result.put(nameSpace, biblioReferenceMap);
377

    
378
			
379
		} catch (SQLException e) {
380
			throw new RuntimeException(e);
381
		}
382
		return result;
383
	}
384

    
385
	/* (non-Javadoc)
386
	 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doCheck(eu.etaxonomy.cdm.io.common.IoStateBase)
387
	 */
388
	@Override
389
	protected boolean doCheck(BerlinModelImportState state){
390
		IOValidator<BerlinModelImportState> validator = new AlgaTerraSpecimenImportValidator();
391
		return validator.validate(state);
392
	}
393

    
394

    
395
	/* (non-Javadoc)
396
	 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#isIgnore(eu.etaxonomy.cdm.io.common.IImportConfigurator)
397
	 */
398
	protected boolean isIgnore(BerlinModelImportState state){
399
		return ! ((AlgaTerraImportState)state).getAlgaTerraConfigurator().isDoEcoFacts();
400
	}
401
	
402
}
(4-4/15)