Project

General

Profile

« Previous | Next » 

Revision 84a5c63d

Added by Andreas Müller over 11 years ago

first implementation of Types in AlgaTerra

View differences:

.gitattributes
101 101
app-import/src/main/java/eu/etaxonomy/cdm/io/algaterra/AlgaTerraImportConfigurator.java -text
102 102
app-import/src/main/java/eu/etaxonomy/cdm/io/algaterra/AlgaTerraImportState.java -text
103 103
app-import/src/main/java/eu/etaxonomy/cdm/io/algaterra/AlgaTerraSpecimenImport.java -text
104
app-import/src/main/java/eu/etaxonomy/cdm/io/algaterra/AlgaTerraSpecimenImportBase.java -text
105
app-import/src/main/java/eu/etaxonomy/cdm/io/algaterra/AlgaTerraTypeImport.java -text
104 106
app-import/src/main/java/eu/etaxonomy/cdm/io/algaterra/validation/AlgaTerraSpecimenImportValidator.java -text
107
app-import/src/main/java/eu/etaxonomy/cdm/io/algaterra/validation/AlgaTerraTypeImportValidator.java -text
105 108
app-import/src/main/java/eu/etaxonomy/cdm/io/cyprus/CyprusDistributionImport.java -text
106 109
app-import/src/main/java/eu/etaxonomy/cdm/io/cyprus/CyprusDistributionRow.java -text
107 110
app-import/src/main/java/eu/etaxonomy/cdm/io/cyprus/CyprusExcelImport.java -text
app-import/src/main/java/eu/etaxonomy/cdm/io/algaterra/AlgaTerraImportConfigurator.java
56 56
				, BerlinModelTaxonNameImport.class
57 57
				, BerlinModelTaxonNameRelationImport.class
58 58
				, BerlinModelNameStatusImport.class
59
				, BerlinModelTypesImport.class
59
				
60 60
				, BerlinModelTaxonImport.class
61 61
				, BerlinModelTaxonRelationImport.class
62
				, BerlinModelCommonNamesImport.class
62
				
63 63
				, BerlinModelFactsImport.class
64
				, BerlinModelOccurrenceImport.class
65
				, BerlinModelOccurrenceSourceImport.class
66 64
				, BerlinModelWebMarkerCategoryImport.class
67 65
				, BerlinModelWebMarkerImport.class
68 66
				
69 67
				, AlgaTerraSpecimenImport.class
68
				, AlgaTerraTypeImport.class
70 69
				
71 70
		};	
72 71
		
app-import/src/main/java/eu/etaxonomy/cdm/io/algaterra/AlgaTerraSpecimenImport.java
9 9

  
10 10
package eu.etaxonomy.cdm.io.algaterra;
11 11

  
12
import java.net.URI;
13
import java.sql.Date;
14 12
import java.sql.ResultSet;
15 13
import java.sql.SQLException;
16 14
import java.util.HashMap;
......
22 20
import org.apache.commons.lang.StringUtils;
23 21
import org.apache.log4j.Logger;
24 22
import org.springframework.stereotype.Component;
25
import org.springframework.transaction.TransactionStatus;
26 23

  
27 24
import eu.etaxonomy.cdm.api.facade.DerivedUnitFacade;
28 25
import eu.etaxonomy.cdm.api.facade.DerivedUnitFacade.DerivedUnitType;
29 26
import eu.etaxonomy.cdm.api.facade.DerivedUnitFacadeNotSupportedException;
30 27
import eu.etaxonomy.cdm.io.algaterra.validation.AlgaTerraSpecimenImportValidator;
31
import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportBase;
32 28
import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportConfigurator;
33 29
import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportState;
34 30
import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelTaxonImport;
35 31
import eu.etaxonomy.cdm.io.common.IOValidator;
36 32
import eu.etaxonomy.cdm.io.common.ResultSetPartitioner;
37
import eu.etaxonomy.cdm.io.common.Source;
38
import eu.etaxonomy.cdm.model.agent.Team;
39 33
import eu.etaxonomy.cdm.model.common.CdmBase;
40 34
import eu.etaxonomy.cdm.model.common.DefinedTermBase;
41 35
import eu.etaxonomy.cdm.model.common.Language;
42 36
import eu.etaxonomy.cdm.model.common.Marker;
43 37
import eu.etaxonomy.cdm.model.common.MarkerType;
44
import eu.etaxonomy.cdm.model.common.OrderedTermVocabulary;
45 38
import eu.etaxonomy.cdm.model.common.TermVocabulary;
46
import eu.etaxonomy.cdm.model.common.TimePeriod;
47 39
import eu.etaxonomy.cdm.model.description.CategoricalData;
48 40
import eu.etaxonomy.cdm.model.description.DescriptionBase;
49 41
import eu.etaxonomy.cdm.model.description.Feature;
......
51 43
import eu.etaxonomy.cdm.model.description.MeasurementUnit;
52 44
import eu.etaxonomy.cdm.model.description.Modifier;
53 45
import eu.etaxonomy.cdm.model.description.QuantitativeData;
54
import eu.etaxonomy.cdm.model.description.SpecimenDescription;
55 46
import eu.etaxonomy.cdm.model.description.State;
56 47
import eu.etaxonomy.cdm.model.description.StatisticalMeasure;
57 48
import eu.etaxonomy.cdm.model.description.StatisticalMeasurementValue;
58 49
import eu.etaxonomy.cdm.model.description.TaxonDescription;
59 50
import eu.etaxonomy.cdm.model.description.TextData;
60
import eu.etaxonomy.cdm.model.location.NamedArea;
61
import eu.etaxonomy.cdm.model.location.Point;
62
import eu.etaxonomy.cdm.model.location.ReferenceSystem;
63
import eu.etaxonomy.cdm.model.location.TdwgArea;
64
import eu.etaxonomy.cdm.model.location.WaterbodyOrCountry;
65 51
import eu.etaxonomy.cdm.model.name.BotanicalName;
66 52
import eu.etaxonomy.cdm.model.name.Rank;
67 53
import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
......
73 59

  
74 60
/**
75 61
 * @author a.mueller
76
 * @created 20.03.2008
77
 * @version 1.0
62
 * @created 01.09.2012
78 63
 */
79 64
@Component
80
public class AlgaTerraSpecimenImport  extends BerlinModelImportBase {
65
public class AlgaTerraSpecimenImport  extends AlgaTerraSpecimenImportBase {
81 66
	private static final Logger logger = Logger.getLogger(AlgaTerraSpecimenImport.class);
82 67

  
83
	public static final String ECO_FACT_NAMESPACE = "EcoFact";
84
	public static final String TERMS_NAMESPACE = "ALGA_TERRA_TERMS";
85
	
86
	//TODO move to transformrer
87
	final static UUID uuidMarkerAlkalinity = UUID.fromString("e52d0ea2-0c1f-4d95-ae6d-e21ab317c594");  
88
	final static UUID uuidRefSystemGps = UUID.fromString("c23e4928-c137-4e4a-b6ab-b430da3d0b94");  
89
	final static UUID uuidFeatureSpecimenCommunity = UUID.fromString("3ff5b1ab-3999-4b5a-b8f7-01fd2f6c12c7");
90
	final static UUID uuidFeatureAdditionalData = UUID.fromString("0ac82ab8-2c2b-4953-98eb-a9f718eb9c57");
91
	final static UUID uuidFeatureHabitatExplanation = UUID.fromString("6fe32295-61a3-44fc-9fcf-a85790ea888f");
92
	
93
	final static UUID uuidVocAlgaTerraClimate = UUID.fromString("b0a677c6-8bb6-43f4-b1b8-fc377a10feb5");
94
	final static UUID uuidVocAlgaTerraHabitat = UUID.fromString("06f30114-e19c-4e7d-a8e5-5488c41fcbc5");
95
	final static UUID uuidVocAlgaTerraLifeForm = UUID.fromString("3c0b194e-809c-4b42-9498-6ff034066ed7");
96
	
97
	final static UUID uuidFeatureAlgaTerraClimate = UUID.fromString("8754674c-9ab9-4f28-95f1-91eeee2314ee");
98
	final static UUID uuidFeatureAlgaTerraHabitat = UUID.fromString("7def3fc2-cdc5-4739-8e13-62edbd053415");
99
	final static UUID uuidFeatureAlgaTerraLifeForm = UUID.fromString("9b657901-1b0d-4a2a-8d21-dd8c1413e2e6");
100
	
101
	final static UUID uuidVocParameter = UUID.fromString("45888b40-5bbb-4293-aa1e-02479796cd7c");
102
	final static UUID uuidStatMeasureSingleValue = UUID.fromString("eb4c3d98-4d4b-4c37-8eb4-17315ce79920");
103
	final static UUID uuidMeasurementValueModifier = UUID.fromString("0218a7a3-f6c0-4d06-a4f8-6b50b73aef5e");
104
	
105
	final static UUID uuidModifierLowerThan = UUID.fromString("2b500085-6bef-4003-b6ea-e0ad0237d79d");
106
	final static UUID uuidModifierGreaterThan = UUID.fromString("828df49d-c745-48f7-b083-0ada43356c34");
107 68
	
108 69
	private static int modCount = 5000;
109 70
	private static final String pluralString = "specimen and observation";
......
135 96
	 */
136 97
	@Override
137 98
	protected String getRecordQuery(BerlinModelImportConfigurator config) {
138
			String strQuery =   //DISTINCT because otherwise emOccurrenceSource creates multiple records for a single distribution 
99
			String strQuery =   
139 100
            " SELECT PTaxon.RIdentifier as taxonId, Fact.FactId, Fact.RecordBasis, EcoFact.*, " + 
140 101
               " tg.ID AS GazetteerId, tg.L2Code, tg.L3Code, tg.L4Code, tg.Country, tg.ISOCountry, " +
141 102
               " ec.UUID as climateUuid, eh.UUID as habitatUuid, elf.UUID as lifeFormUuid" +
......
198 159
					//field observation
199 160
					handleSingleSpecimen(rs, facade, state);
200 161
					
162
					handleEcoFactSpecificSpecimen(rs,facade, state);
163
					
201 164
					state.setCurrentFieldObservationNotNew(false);
202 165
					
203 166
					//description element
......
232 195

  
233 196

  
234 197

  
198
	private void handleEcoFactSpecificSpecimen(ResultSet rs, DerivedUnitFacade facade, AlgaTerraImportState state) throws SQLException {
199
		
200
		Object alkalinityFlag = rs.getBoolean("AlkalinityFlag");
201
		
202
		//alkalinity marker
203
		if (alkalinityFlag != null){
204
			MarkerType alkalinityMarkerType = getMarkerType(state, uuidMarkerAlkalinity, "Alkalinity", "Alkalinity", null);
205
			boolean alkFlag = Boolean.valueOf(alkalinityFlag.toString());
206
			Marker alkalinityMarker = Marker.NewInstance(alkalinityMarkerType, alkFlag);
207
			facade.getFieldObservation(true).addMarker(alkalinityMarker);
208
		}
209
		
210
		
211
		DescriptionBase<?> fieldDescription = getFieldObservationDescription(facade);
235 212

  
236
	/**
237
	 * Creates the vocabularies and the features for Climate, Habitat and Lifeform
238
	 * @param state
239
	 * @throws SQLException
240
	 */
241
	private void makeVocabulariesAndFeatures(AlgaTerraImportState state) throws SQLException {
242
		String abbrevLabel = null;
243
		URI uri = null;
213
		//habitat, ecology, community, etc.
214
		String habitat = rs.getString("HabitatExplanation");
244 215
		
245
		if (! state.isSpecimenVocabulariesCreated()){
246
			
247
			TransactionStatus txStatus = this.startTransaction();
216
		if (isNotBlank(habitat)){
217
			Feature habitatExplanation = getFeature(state, uuidFeatureHabitatExplanation, "Habitat Explanation", "HabitatExplanation", null, null);
218
			TextData textData = TextData.NewInstance(habitatExplanation);
219
			textData.putText(Language.DEFAULT(), habitat);
220
			fieldDescription.addElement(textData);
221
		}
248 222
		
249
			boolean isOrdered = true;
250
			OrderedTermVocabulary<State> climateVoc = (OrderedTermVocabulary)getVocabulary(uuidVocAlgaTerraClimate, "Climate", "Climate", abbrevLabel, uri, isOrdered, null);
251
			OrderedTermVocabulary<State> habitatVoc = (OrderedTermVocabulary)getVocabulary(uuidVocAlgaTerraHabitat, "Habitat", "Habitat", abbrevLabel, uri, isOrdered, null);
252
			OrderedTermVocabulary<State> lifeformVoc = (OrderedTermVocabulary)getVocabulary(uuidVocAlgaTerraLifeForm, "Lifeform", "Lifeform", abbrevLabel, uri, isOrdered, null);
253
			
254
			
255
			Feature feature = getFeature(state, uuidFeatureAlgaTerraClimate, "Climate","Climate", null, null);
256
			feature.setSupportsCategoricalData(true);
257
			
258
			feature = getFeature(state, uuidFeatureAlgaTerraLifeForm, "LifeForm","LifeForm", null, null);
259
			feature.setSupportsCategoricalData(true);
260
			
261
			feature = Feature.HABITAT();
262
			feature.setSupportsCategoricalData(true);
263
			getTermService().saveOrUpdate(feature);
264
			
265
			Source source = state.getAlgaTerraConfigurator().getSource();
266
			
267
			String climateSql = "SELECT * FROM EcoClimate";
268
			ResultSet rs = source.getResultSet(climateSql);
269
			while (rs.next()){
270
				String climate = rs.getString("Climate");
271
				String description = rs.getString("Description");
272
				Integer id = rs.getInt("ClimateId");
273
				UUID uuid = UUID.fromString(rs.getString("UUID"));
274
				State stateTerm = getStateTerm(state, uuid, climate, description, null, climateVoc);
275
				addOriginalSource(stateTerm, id.toString(), "EcoClimate", state.getTransactionalSourceReference());
276
				getTermService().saveOrUpdate(stateTerm);
277
			}
278
			
279
			String habitatSql = "SELECT * FROM EcoHabitat";
280
			rs = source.getResultSet(habitatSql);
281
			while (rs.next()){
282
				String habitat = rs.getString("Habitat");
283
				String description = rs.getString("Description");
284
				Integer id = rs.getInt("HabitatId");
285
				UUID uuid = UUID.fromString(rs.getString("UUID"));
286
				State stateTerm = getStateTerm(state, uuid, habitat, description, null, habitatVoc);
287
				addOriginalSource(stateTerm, id.toString(), "EcoHabitat", state.getTransactionalSourceReference());
288
				getTermService().saveOrUpdate(stateTerm);
289
			}
290
			
291
			String lifeformSql = "SELECT * FROM EcoLifeForm";
292
			rs = source.getResultSet(lifeformSql);
293
			while (rs.next()){
294
				String lifeform = rs.getString("LifeForm");
295
				String description = rs.getString("Description");
296
				Integer id = rs.getInt("LifeFormId");
297
				UUID uuid = UUID.fromString(rs.getString("UUID"));
298
				State stateTerm = getStateTerm(state, uuid, lifeform, description, null, lifeformVoc);
299
				addOriginalSource(stateTerm, id.toString(), "EcoLifeForm", state.getTransactionalSourceReference());
300
				getTermService().saveOrUpdate(stateTerm);
301
			}
302
			
303
			this.commitTransaction(txStatus);
304
			
305
			state.setSpecimenVocabulariesCreated(true);
223
		String community = rs.getString("Comunity");
224
		if (isNotBlank(community)){
225
			Feature communityFeature = getFeature(state, uuidFeatureSpecimenCommunity, "Community", "The community of a specimen (e.g. other algae in the same sample)", null, null);
226
			TextData textData = TextData.NewInstance(communityFeature);
227
			textData.putText(Language.DEFAULT(), community);
228
			fieldDescription.addElement(textData);
229
		}
230

  
231
		String additionalData = rs.getString("AdditionalData");
232
		if (isNotBlank(additionalData)){  //or handle it as Annotation ??
233
			Feature additionalDataFeature = getFeature(state, uuidFeatureAdditionalData, "Additional Data", "Additional Data", null, null);
234
			TextData textData = TextData.NewInstance(additionalDataFeature);
235
			textData.putText(Language.DEFAULT(), additionalData);
236
			fieldDescription.addElement(textData);
237
		}
238
		
239
		String climateUuid = rs.getString("climateUuid");
240
		String habitatUuid = rs.getString("habitatUuid");
241
		String lifeFormUuid = rs.getString("lifeFormUuid");
242
		
243
		addCategoricalValue(state, fieldDescription, climateUuid, uuidFeatureAlgaTerraClimate);
244
		addCategoricalValue(state, fieldDescription, habitatUuid, Feature.HABITAT().getUuid());
245
		addCategoricalValue(state, fieldDescription, lifeFormUuid, uuidFeatureAlgaTerraLifeForm);
246
		
247
		
248
		//collection
249
		String voucher = rs.getString("Voucher");
250
		if (StringUtils.isNotBlank(voucher)){
251
			facade.setAccessionNumber(voucher);
306 252
		}
307 253
		
254
		//parameters
255
		makeParameter(state, rs, getFieldObservationDescription(facade));
256

  
308 257
	}
309 258

  
310 259

  
311 260

  
312
	private void handleSingleSpecimen(ResultSet rs, DerivedUnitFacade facade, AlgaTerraImportState state) throws SQLException {
313
		//FIXME missing fields #3084, #3085, #3080
314
		try {
315
			Object alkalinityFlag = rs.getBoolean("AlkalinityFlag");
316
			
317
			String locality = rs.getString("Locality");
318
			Double latitude = nullSafeDouble(rs, "Latitude");
319
			Double longitude = nullSafeDouble(rs, "Longitude");
320
			Integer errorRadius = nullSafeInt(rs,"Prec");
321
			String geoCodeMethod = rs.getString("GeoCodeMethod");
322
			
323
			Integer altitude = nullSafeInt(rs, "Altitude");
324
			Integer lowerAltitude = nullSafeInt(rs,"AltitudeLowerValue");
325
			String altitudeUnit = rs.getString("AltitudeUnit");
326
			Double depth = nullSafeDouble(rs, "Depth");
327
			Double depthLow = nullSafeDouble(rs, "DepthLow");
328
			   	
329
			String collectorsNumber = rs.getString("CollectorsNumber");
330
			Date collectionDateStart = rs.getDate("CollectionDate");
331
			Date collectionDateEnd = rs.getDate("CollectionDateEnd");
332
			
333
			String climateUuid = rs.getString("climateUuid");
334
			String habitatUuid = rs.getString("habitatUuid");
335
			String lifeFormUuid = rs.getString("lifeFormUuid");
336
			
337
			String habitat = rs.getString("HabitatExplanation");
338
			String community = rs.getString("Comunity");
339
			String additionalData = rs.getString("AdditionalData");
340
			
341
			
342
			
343
			FieldObservation fieldObservation = facade.getFieldObservation(true);
344
			
345
			//alkalinity marker
346
			if (alkalinityFlag != null){
347
				MarkerType alkalinityMarkerType = getMarkerType(state, uuidMarkerAlkalinity, "Alkalinity", "Alkalinity", null);
348
				boolean alkFlag = Boolean.valueOf(alkalinityFlag.toString());
349
				Marker alkalinityMarker = Marker.NewInstance(alkalinityMarkerType, alkFlag);
350
				fieldObservation.addMarker(alkalinityMarker);
351
			}
352
			
353
			//location
354
			facade.setLocality(locality);
355
			    	
356
			//exact location
357
			ReferenceSystem referenceSystem = makeRefrenceSystem(geoCodeMethod, state);
358
			Point exactLocation = Point.NewInstance(longitude, latitude, referenceSystem, errorRadius);
359
			facade.setExactLocation(exactLocation);
360
			
361
			//altitude, depth
362
			if (StringUtils.isNotBlank(altitudeUnit) && ! altitudeUnit.trim().equalsIgnoreCase("m")){
363
				logger.warn("Altitude unit is not [m] but: " +  altitudeUnit);
364
			}
365
			if ( altitude != null){
366
				if (lowerAltitude == null){
367
					facade.setAbsoluteElevation(altitude);
368
				}else{
369
			   		if (! facade.isEvenDistance(lowerAltitude, altitude)){
370
			   			//FIXME there is a ticket for this
371
			   			altitude = altitude + 1;
372
			   			logger.warn("Current implementation of altitude does not allow uneven distances");
373
			   		}
374
					facade.setAbsoluteElevationRange(lowerAltitude,altitude);
375
			   	}
376
			}
377
			if ( depth != null){
378
				//FIXME needs model change to accept double #3072
379
				Integer intDepth = depth.intValue();
380
				if (depthLow == null){
381
					facade.setDistanceToWaterSurface(intDepth);
382
				}else{
383
					//FIXME range not yet in model #3074
384
			   		facade.setDistanceToWaterSurface(intDepth);
385
			   	}
386
			}
387
			
388
			//habitat, ecology, community, etc.
389
			DescriptionBase<?> fieldDescription = getFieldObservationDescription(facade);
390
			
391
			addCategoricalValue(state, fieldDescription, climateUuid, uuidFeatureAlgaTerraClimate);
392
			addCategoricalValue(state, fieldDescription, habitatUuid, Feature.HABITAT().getUuid());
393
			addCategoricalValue(state, fieldDescription, lifeFormUuid, uuidFeatureAlgaTerraLifeForm);
394
			
395
			if (isNotBlank(habitat)){
396
				Feature habitatExplanation = getFeature(state, uuidFeatureHabitatExplanation, "Habitat Explanation", "HabitatExplanation", null, null);
397
				TextData textData = TextData.NewInstance(habitatExplanation);
398
				textData.putText(Language.DEFAULT(), habitat);
399
				getFieldObservationDescription(facade).addElement(textData);
400
			}
401
			if (isNotBlank(community)){
402
				Feature communityFeature = getFeature(state, uuidFeatureSpecimenCommunity, "Community", "The community of a specimen (e.g. other algae in the same sample)", null, null);
403
				TextData textData = TextData.NewInstance(communityFeature);
404
				textData.putText(Language.DEFAULT(), community);
405
				getFieldObservationDescription(facade).addElement(textData);
406
			}
407
			if (isNotBlank(additionalData)){  //or handle it as Annotation ??
408
				Feature additionalDataFeature = getFeature(state, uuidFeatureAdditionalData, "Additional Data", "Additional Data", null, null);
409
				TextData textData = TextData.NewInstance(additionalDataFeature);
410
				textData.putText(Language.DEFAULT(), additionalData);
411
				getFieldObservationDescription(facade).addElement(textData);
412
			}
413
			
414
			//field
415
			facade.setFieldNumber(collectorsNumber);
416
			TimePeriod gatheringPeriod = TimePeriod.NewInstance(collectionDateStart, collectionDateEnd);
417
			facade.setGatheringPeriod(gatheringPeriod);
418
			handleCollectorTeam(state, facade, rs);
419
			
420
			//areas
421
			makeAreas(state, rs, facade);
422
			
423
			//parameters
424
			makeParameter(state, rs, getFieldObservationDescription(facade));
425
			
426
			//collection
427
			String voucher = rs.getString("Voucher");
428
			if (StringUtils.isNotBlank(voucher)){
429
				facade.setAccessionNumber(voucher);
430
			}
431
			
432
			
433
			//notes
434
			//TODO is this an annotation on field observation or on the derived unit?
435
			
436
			//TODO id, created for fact +  ecoFact
437
			//    	this.doIdCreatedUpdatedNotes(state, descriptionElement, rs, id, namespace);
438
		
439
		} catch (Exception e) {
440
			throw new RuntimeException(e);
261

  
262
	private void addCategoricalValue(AlgaTerraImportState importState, DescriptionBase description, String uuidTerm, UUID featureUuid) {
263
		if (uuidTerm != null){
264
			State state = this.getStateTerm(importState, UUID.fromString(uuidTerm));
265
			Feature feature = getFeature(importState, featureUuid);
266
			CategoricalData categoricalData = CategoricalData.NewInstance(state, feature);
267
			description.addElement(categoricalData);
441 268
		}
442
    	
443 269
	}
444 270

  
445

  
446 271
	private void makeParameter(AlgaTerraImportState state, ResultSet rs, DescriptionBase<?> descriptionBase) throws SQLException {
447 272
		for (int i = 1; i <= 10; i++){
448 273
			String valueStr = rs.getString(String.format("P%dValue", i));
......
526 351
	 * @return
527 352
	 */
528 353
	private MeasurementUnit getMeasurementUnit(AlgaTerraImportState state, String unitStr) {
529
		MeasurementUnit result = null;
530 354
		if (StringUtils.isNotBlank(unitStr)){
531 355
			UUID uuidMeasurementUnitMgL = UUID.fromString("7ac302c5-3cbd-4334-964a-bf5d11eb9ead");
532 356
			UUID uuidMeasurementUnitMolMol = UUID.fromString("96b78d78-3e49-448f-8100-e7779b71dd53");
......
539 363
			
540 364
			
541 365
			if (unitStr.equalsIgnoreCase("mg/L")){
542
				return  getMeasurementUnit(state, uuidMeasurementUnitMgL, unitStr, unitStr, unitStr, null);
366
				return getMeasurementUnit(state, uuidMeasurementUnitMgL, unitStr, unitStr, unitStr, null);
543 367
			}else if (unitStr.equalsIgnoreCase("mol/mol")){
544
				return result = getMeasurementUnit(state, uuidMeasurementUnitMolMol, unitStr, unitStr, unitStr, null);
368
				return getMeasurementUnit(state, uuidMeasurementUnitMolMol, unitStr, unitStr, unitStr, null);
545 369
			}else if (unitStr.equalsIgnoreCase("\u00B5mol Si/L")){   //µmol Si/L
546 370
				return getMeasurementUnit(state, uuidMeasurementUnitMicroMolSiL, unitStr, unitStr, unitStr, null);
547 371
			}else if (unitStr.equalsIgnoreCase("\u00B5mol/L")){		//µmol/L
......
565 389

  
566 390

  
567 391

  
568
	private void addCategoricalValue(AlgaTerraImportState importState, DescriptionBase description, String uuidTerm, UUID featureUuid) {
569
		if (uuidTerm != null){
570
			State state = this.getStateTerm(importState, UUID.fromString(uuidTerm));
571
			Feature feature = getFeature(importState, featureUuid);
572
			CategoricalData categoricalData = CategoricalData.NewInstance(state, feature);
573
			description.addElement(categoricalData);
574
		}
575
	}
576

  
577

  
578
	private void handleCollectorTeam(AlgaTerraImportState state, DerivedUnitFacade facade, ResultSet rs) throws SQLException {
579
		// FIXME parsen
580
		String collector = rs.getString("Collector");
581
		Team team = Team.NewTitledInstance(collector, collector);
582
		facade.setCollector(team);
583
		
584
		
585
		
586
	}
587 392

  
588
	private void makeAreas(AlgaTerraImportState state, ResultSet rs, DerivedUnitFacade facade) throws SQLException {
589
	   	Object gazetteerId = rs.getObject("GazetteerId");
590
	   	if (gazetteerId != null){
591
	   		//TDWG
592
	   		NamedArea tdwgArea;
593
	   		String tdwg4 = rs.getString("L4Code");
594
	   		if (isNotBlank(tdwg4)){
595
	   			tdwgArea = TdwgArea.getAreaByTdwgAbbreviation(tdwg4);
596
	   		}else{
597
	   			String tdwg3 = rs.getString("L3Code");
598
	   			if (isNotBlank(tdwg3)){
599
	   				tdwgArea = TdwgArea.getAreaByTdwgAbbreviation(tdwg3);
600
	   			}else{
601
	   				Integer tdwg2 = rs.getInt("L2Code");   				
602
	   				tdwgArea = TdwgArea.getAreaByTdwgAbbreviation(String.valueOf(tdwg2));
603
		   		}
604
	   		}
605
	   		if (tdwgArea == null){
606
	   			logger.warn("TDWG area could not be defined for gazetterId: " + gazetteerId);
607
	   		}else{
608
	   			facade.addCollectingArea(tdwgArea);
609
	   		}
610
	   		
611
	   		//Countries
612
	   		WaterbodyOrCountry country = null;
613
	   		String isoCountry = rs.getString("ISOCountry");
614
	   		String countryStr = rs.getString("Country");
615
	   		if (isNotBlank(isoCountry)){
616
		   		country = WaterbodyOrCountry.getWaterbodyOrCountryByIso3166A2(isoCountry);
617
	   		}else if (isNotBlank(countryStr)){
618
	   			logger.warn("Country exists but no ISO code");
619
	   		}
620
	   		if (country == null){
621
	   			logger.warn("Country does not exist for GazetteerID " + gazetteerId);
622
	   		}else{
623
	   			facade.setCountry(country);
624
	   		}
625
	   		
626
	   	}
627
	    
628
	   	//Waterbody
629
	   	WaterbodyOrCountry waterbody = null;
630
	   	String waterbodyStr = rs.getString("WaterBody");
631
	   	if (isNotBlank(waterbodyStr)){
632
	   		if (waterbodyStr.equals("Atlantic Ocean")){
633
	   			waterbody = WaterbodyOrCountry.ATLANTICOCEAN();
634
	   		}else{
635
	   			logger.warn("Waterbody not recognized: " + waterbody);
636
	   		}
637
	   		if (waterbody != null){
638
	   			facade.addCollectingArea(waterbody);
639
	   		}
640
	   	}
641

  
642
		
643
	   	//countries sub
644
	   	//TODO
645
	}
646

  
647
	private DescriptionBase getFieldObservationDescription(DerivedUnitFacade facade) {
648
		Set<DescriptionBase> descriptions = facade.innerFieldObservation().getDescriptions();
649
		for (DescriptionBase desc : descriptions){
650
			if (desc.isImageGallery() == false){
651
				return desc;
652
			}
653
		}
654
		SpecimenDescription specDesc = SpecimenDescription.NewInstance(facade.innerFieldObservation());
655
		descriptions.add(specDesc);
656
		return specDesc;
657
	}
658

  
659
	private ReferenceSystem makeRefrenceSystem(String geoCodeMethod, AlgaTerraImportState state) {
660
		if (StringUtils.isBlank(geoCodeMethod)){
661
			return null;
662
		}else if(geoCodeMethod.startsWith("GPS")){
663
			getReferenceSystem(state, uuidRefSystemGps, "GPS", "GPS", "GPS", ReferenceSystem.GOOGLE_EARTH().getVocabulary());
664
			return ReferenceSystem.WGS84(); 
665
		}else if(geoCodeMethod.startsWith("Google")){
666
			return ReferenceSystem.GOOGLE_EARTH();
667
		}else if(geoCodeMethod.startsWith("Map")){
668
			logger.warn("Reference system " +  geoCodeMethod +  " not yet supported.");
669
			return null;
670
		}else if(geoCodeMethod.startsWith("WikiProjekt Georeferenzierung") || geoCodeMethod.startsWith("http://toolserver.org/~geohack/geohack.php") ){
671
			return ReferenceSystem.WGS84();
672
		}else {
673
			logger.warn("Reference system " +  geoCodeMethod +  " not yet supported.");
674
			return null;
675
		}
676
	}
677 393

  
678 394
	/**
679 395
	 * @param state
......
768 484
			//field observation map map
769 485
			nameSpace = AlgaTerraSpecimenImport.ECO_FACT_NAMESPACE;
770 486
			cdmClass = FieldObservation.class;
771
			idSet = taxonIdSet;
487
			idSet = fieldObservationIdSet;
772 488
			Map<String, FieldObservation> fieldObservationMap = (Map<String, FieldObservation>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
773 489
			result.put(nameSpace, fieldObservationMap);
774 490

  
775 491
			//terms
776 492
			nameSpace = AlgaTerraSpecimenImport.TERMS_NAMESPACE;
777 493
			cdmClass = FieldObservation.class;
778
			idSet = taxonIdSet;
494
			idSet = termsIdSet;
779 495
			Map<String, DefinedTermBase> termMap = (Map<String, DefinedTermBase>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
780 496
			result.put(nameSpace, termMap);
781

  
782
		
783
			
784 497
			
785 498
		} catch (SQLException e) {
786 499
			throw new RuntimeException(e);
app-import/src/main/java/eu/etaxonomy/cdm/io/algaterra/AlgaTerraSpecimenImportBase.java
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.net.URI;
13
import java.sql.Date;
14
import java.sql.ResultSet;
15
import java.sql.SQLException;
16
import java.util.Set;
17
import java.util.UUID;
18

  
19
import org.apache.commons.lang.StringUtils;
20
import org.apache.log4j.Logger;
21
import org.springframework.transaction.TransactionStatus;
22

  
23
import eu.etaxonomy.cdm.api.facade.DerivedUnitFacade;
24
import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportBase;
25
import eu.etaxonomy.cdm.io.common.Source;
26
import eu.etaxonomy.cdm.model.agent.Team;
27
import eu.etaxonomy.cdm.model.common.OrderedTermVocabulary;
28
import eu.etaxonomy.cdm.model.common.TimePeriod;
29
import eu.etaxonomy.cdm.model.description.DescriptionBase;
30
import eu.etaxonomy.cdm.model.description.Feature;
31
import eu.etaxonomy.cdm.model.description.SpecimenDescription;
32
import eu.etaxonomy.cdm.model.description.State;
33
import eu.etaxonomy.cdm.model.location.NamedArea;
34
import eu.etaxonomy.cdm.model.location.Point;
35
import eu.etaxonomy.cdm.model.location.ReferenceSystem;
36
import eu.etaxonomy.cdm.model.location.TdwgArea;
37
import eu.etaxonomy.cdm.model.location.WaterbodyOrCountry;
38

  
39
/**
40
 * @author a.mueller
41
 * @created 12.09.2012
42
 */
43
public abstract class AlgaTerraSpecimenImportBase extends BerlinModelImportBase{
44
	private static final Logger logger = Logger.getLogger(AlgaTerraSpecimenImportBase.class);
45

  
46
	public static final String ECO_FACT_NAMESPACE = "EcoFact";
47
	public static final String TYPE_SPECIMEN_NAMESPACE = "TypeSpecimen";
48
	public static final String TERMS_NAMESPACE = "ALGA_TERRA_TERMS";
49
	
50
	//TODO move to transformrer
51
	final static UUID uuidMarkerAlkalinity = UUID.fromString("e52d0ea2-0c1f-4d95-ae6d-e21ab317c594");  
52
	final static UUID uuidRefSystemGps = UUID.fromString("c23e4928-c137-4e4a-b6ab-b430da3d0b94");  
53
	final static UUID uuidFeatureSpecimenCommunity = UUID.fromString("3ff5b1ab-3999-4b5a-b8f7-01fd2f6c12c7");
54
	final static UUID uuidFeatureAdditionalData = UUID.fromString("0ac82ab8-2c2b-4953-98eb-a9f718eb9c57");
55
	final static UUID uuidFeatureHabitatExplanation = UUID.fromString("6fe32295-61a3-44fc-9fcf-a85790ea888f");
56
	
57
	final static UUID uuidVocAlgaTerraClimate = UUID.fromString("b0a677c6-8bb6-43f4-b1b8-fc377a10feb5");
58
	final static UUID uuidVocAlgaTerraHabitat = UUID.fromString("06f30114-e19c-4e7d-a8e5-5488c41fcbc5");
59
	final static UUID uuidVocAlgaTerraLifeForm = UUID.fromString("3c0b194e-809c-4b42-9498-6ff034066ed7");
60
	
61
	final static UUID uuidFeatureAlgaTerraClimate = UUID.fromString("8754674c-9ab9-4f28-95f1-91eeee2314ee");
62
	final static UUID uuidFeatureAlgaTerraHabitat = UUID.fromString("7def3fc2-cdc5-4739-8e13-62edbd053415");
63
	final static UUID uuidFeatureAlgaTerraLifeForm = UUID.fromString("9b657901-1b0d-4a2a-8d21-dd8c1413e2e6");
64
	
65
	final static UUID uuidVocParameter = UUID.fromString("45888b40-5bbb-4293-aa1e-02479796cd7c");
66
	final static UUID uuidStatMeasureSingleValue = UUID.fromString("eb4c3d98-4d4b-4c37-8eb4-17315ce79920");
67
	final static UUID uuidMeasurementValueModifier = UUID.fromString("0218a7a3-f6c0-4d06-a4f8-6b50b73aef5e");
68
	
69
	final static UUID uuidModifierLowerThan = UUID.fromString("2b500085-6bef-4003-b6ea-e0ad0237d79d");
70
	final static UUID uuidModifierGreaterThan = UUID.fromString("828df49d-c745-48f7-b083-0ada43356c34");
71

  
72

  
73
	/**
74
	 * Creates the vocabularies and the features for Climate, Habitat and Lifeform
75
	 * @param state
76
	 * @throws SQLException
77
	 */
78
	protected void makeVocabulariesAndFeatures(AlgaTerraImportState state) throws SQLException {
79
		String abbrevLabel = null;
80
		URI uri = null;
81
		
82
		if (! state.isSpecimenVocabulariesCreated()){
83
			
84
			TransactionStatus txStatus = this.startTransaction();
85
		
86
			boolean isOrdered = true;
87
			OrderedTermVocabulary<State> climateVoc = (OrderedTermVocabulary)getVocabulary(uuidVocAlgaTerraClimate, "Climate", "Climate", abbrevLabel, uri, isOrdered, null);
88
			OrderedTermVocabulary<State> habitatVoc = (OrderedTermVocabulary)getVocabulary(uuidVocAlgaTerraHabitat, "Habitat", "Habitat", abbrevLabel, uri, isOrdered, null);
89
			OrderedTermVocabulary<State> lifeformVoc = (OrderedTermVocabulary)getVocabulary(uuidVocAlgaTerraLifeForm, "Lifeform", "Lifeform", abbrevLabel, uri, isOrdered, null);
90
			
91
			
92
			Feature feature = getFeature(state, uuidFeatureAlgaTerraClimate, "Climate","Climate", null, null);
93
			feature.setSupportsCategoricalData(true);
94
			
95
			feature = getFeature(state, uuidFeatureAlgaTerraLifeForm, "LifeForm","LifeForm", null, null);
96
			feature.setSupportsCategoricalData(true);
97
			
98
			feature = Feature.HABITAT();
99
			feature.setSupportsCategoricalData(true);
100
			getTermService().saveOrUpdate(feature);
101
			
102
			Source source = state.getAlgaTerraConfigurator().getSource();
103
			
104
			String climateSql = "SELECT * FROM EcoClimate";
105
			ResultSet rs = source.getResultSet(climateSql);
106
			while (rs.next()){
107
				String climate = rs.getString("Climate");
108
				String description = rs.getString("Description");
109
				Integer id = rs.getInt("ClimateId");
110
				UUID uuid = UUID.fromString(rs.getString("UUID"));
111
				State stateTerm = getStateTerm(state, uuid, climate, description, null, climateVoc);
112
				addOriginalSource(stateTerm, id.toString(), "EcoClimate", state.getTransactionalSourceReference());
113
				getTermService().saveOrUpdate(stateTerm);
114
			}
115
			
116
			String habitatSql = "SELECT * FROM EcoHabitat";
117
			rs = source.getResultSet(habitatSql);
118
			while (rs.next()){
119
				String habitat = rs.getString("Habitat");
120
				String description = rs.getString("Description");
121
				Integer id = rs.getInt("HabitatId");
122
				UUID uuid = UUID.fromString(rs.getString("UUID"));
123
				State stateTerm = getStateTerm(state, uuid, habitat, description, null, habitatVoc);
124
				addOriginalSource(stateTerm, id.toString(), "EcoHabitat", state.getTransactionalSourceReference());
125
				getTermService().saveOrUpdate(stateTerm);
126
			}
127
			
128
			String lifeformSql = "SELECT * FROM EcoLifeForm";
129
			rs = source.getResultSet(lifeformSql);
130
			while (rs.next()){
131
				String lifeform = rs.getString("LifeForm");
132
				String description = rs.getString("Description");
133
				Integer id = rs.getInt("LifeFormId");
134
				UUID uuid = UUID.fromString(rs.getString("UUID"));
135
				State stateTerm = getStateTerm(state, uuid, lifeform, description, null, lifeformVoc);
136
				addOriginalSource(stateTerm, id.toString(), "EcoLifeForm", state.getTransactionalSourceReference());
137
				getTermService().saveOrUpdate(stateTerm);
138
			}
139
			
140
			this.commitTransaction(txStatus);
141
			
142
			state.setSpecimenVocabulariesCreated(true);
143
		}
144
		
145
	}
146
	
147
	protected String getLocalityString(){
148
		return "Locality";
149
	}
150
	
151
	protected void handleSingleSpecimen(ResultSet rs, DerivedUnitFacade facade, AlgaTerraImportState state) throws SQLException {
152
		//FIXME missing fields #3084, #3085, #3080
153
		try {
154
			
155
			String locality = rs.getString(getLocalityString());
156
			Double latitude = nullSafeDouble(rs, "Latitude");
157
			Double longitude = nullSafeDouble(rs, "Longitude");
158
			Integer errorRadius = nullSafeInt(rs,"Prec");
159
			String geoCodeMethod = rs.getString("GeoCodeMethod");
160
			
161
			Integer altitude = nullSafeInt(rs, "Altitude");
162
			Integer lowerAltitude = nullSafeInt(rs,"AltitudeLowerValue");
163
			String altitudeUnit = rs.getString("AltitudeUnit");
164
			Double depth = nullSafeDouble(rs, "Depth");
165
			Double depthLow = nullSafeDouble(rs, "DepthLow");
166
			   	
167
			String collectorsNumber = rs.getString("CollectorsNumber");
168
			Date collectionDateStart = rs.getDate("CollectionDate");
169
			Date collectionDateEnd = rs.getDate("CollectionDateEnd");
170

  
171
			//location
172
			facade.setLocality(locality);
173
			    	
174
			//exact location
175
			ReferenceSystem referenceSystem = makeRefrenceSystem(geoCodeMethod, state);
176
			if (longitude != null || latitude != null || referenceSystem != null || errorRadius != null){
177
				Point exactLocation = Point.NewInstance(longitude, latitude, referenceSystem, errorRadius);
178
				facade.setExactLocation(exactLocation);
179
			}
180
			
181
			//altitude, depth
182
			if (StringUtils.isNotBlank(altitudeUnit) && ! altitudeUnit.trim().equalsIgnoreCase("m")){
183
				logger.warn("Altitude unit is not [m] but: " +  altitudeUnit);
184
			}
185
			if ( altitude != null){
186
				if (lowerAltitude == null){
187
					facade.setAbsoluteElevation(altitude);
188
				}else{
189
			   		if (! facade.isEvenDistance(lowerAltitude, altitude)){
190
			   			//FIXME there is a ticket for this
191
			   			altitude = altitude + 1;
192
			   			logger.info("Current implementation of altitude does not allow uneven distances");
193
			   		}
194
					facade.setAbsoluteElevationRange(lowerAltitude,altitude);
195
			   	}
196
			}
197
			if ( depth != null){
198
				//FIXME needs model change to accept double #3072
199
				Integer intDepth = depth.intValue();
200
				if (depthLow == null){
201
					facade.setDistanceToWaterSurface(intDepth);
202
				}else{
203
					//FIXME range not yet in model #3074
204
			   		facade.setDistanceToWaterSurface(intDepth);
205
			   	}
206
			}
207

  
208
			
209
			//field
210
			facade.setFieldNumber(collectorsNumber);
211
			TimePeriod gatheringPeriod = TimePeriod.NewInstance(collectionDateStart, collectionDateEnd);
212
			facade.setGatheringPeriod(gatheringPeriod);
213
			handleCollectorTeam(state, facade, rs);
214
			
215
			//areas
216
			makeAreas(state, rs, facade);
217
			
218
			
219
			//notes
220
			//TODO is this an annotation on field observation or on the derived unit?
221
			
222
			//TODO id, created for fact +  ecoFact
223
			//    	this.doIdCreatedUpdatedNotes(state, descriptionElement, rs, id, namespace);
224
		
225
		} catch (Exception e) {
226
			throw new RuntimeException(e);
227
		}
228
    	
229
	}
230
	
231
	protected DescriptionBase getFieldObservationDescription(DerivedUnitFacade facade) {
232
		Set<DescriptionBase> descriptions = facade.innerFieldObservation().getDescriptions();
233
		for (DescriptionBase desc : descriptions){
234
			if (desc.isImageGallery() == false){
235
				return desc;
236
			}
237
		}
238
		SpecimenDescription specDesc = SpecimenDescription.NewInstance(facade.innerFieldObservation());
239
		descriptions.add(specDesc);
240
		return specDesc;
241
	}
242
	
243

  
244
	private void makeAreas(AlgaTerraImportState state, ResultSet rs, DerivedUnitFacade facade) throws SQLException {
245
	   	Object gazetteerId = rs.getObject("GazetteerId");
246
	   	if (gazetteerId != null){
247
	   		//TDWG
248
	   		NamedArea tdwgArea;
249
	   		String tdwg4 = rs.getString("L4Code");
250
	   		if (isNotBlank(tdwg4)){
251
	   			tdwgArea = TdwgArea.getAreaByTdwgAbbreviation(tdwg4);
252
	   		}else{
253
	   			String tdwg3 = rs.getString("L3Code");
254
	   			if (isNotBlank(tdwg3)){
255
	   				tdwgArea = TdwgArea.getAreaByTdwgAbbreviation(tdwg3);
256
	   			}else{
257
	   				Integer tdwg2 = rs.getInt("L2Code");   				
258
	   				tdwgArea = TdwgArea.getAreaByTdwgAbbreviation(String.valueOf(tdwg2));
259
		   		}
260
	   		}
261
	   		if (tdwgArea == null){
262
	   			logger.warn("TDWG area could not be defined for gazetterId: " + gazetteerId);
263
	   		}else{
264
	   			facade.addCollectingArea(tdwgArea);
265
	   		}
266
	   		
267
	   		//Countries
268
	   		WaterbodyOrCountry country = null;
269
	   		String isoCountry = rs.getString("ISOCountry");
270
	   		String countryStr = rs.getString("Country");
271
	   		if (isNotBlank(isoCountry)){
272
		   		country = WaterbodyOrCountry.getWaterbodyOrCountryByIso3166A2(isoCountry);
273
	   		}else if (isNotBlank(countryStr)){
274
	   			logger.warn("Country exists but no ISO code");
275
	   		}
276
	   		if (country == null){
277
	   			logger.warn("Country does not exist for GazetteerID " + gazetteerId);
278
	   		}else{
279
	   			facade.setCountry(country);
280
	   		}
281
	   		
282
	   	}
283
	    
284
	   	//Waterbody
285
	   	WaterbodyOrCountry waterbody = null;
286
	   	String waterbodyStr = rs.getString("WaterBody");
287
	   	if (isNotBlank(waterbodyStr)){
288
	   		if (waterbodyStr.equals("Atlantic Ocean")){
289
	   			waterbody = WaterbodyOrCountry.ATLANTICOCEAN();
290
	   		}else{
291
	   			logger.warn("Waterbody not recognized: " + waterbody);
292
	   		}
293
	   		if (waterbody != null){
294
	   			facade.addCollectingArea(waterbody);
295
	   		}
296
	   	}
297

  
298
		
299
	   	//countries sub
300
	   	//TODO -> SpecimenImport (not existing in TypeSpecimen)
301
	}
302

  
303

  
304
	
305

  
306
	private ReferenceSystem makeRefrenceSystem(String geoCodeMethod, AlgaTerraImportState state) {
307
		if (StringUtils.isBlank(geoCodeMethod)){
308
			return null;
309
		}else if(geoCodeMethod.startsWith("GPS")){
310
			getReferenceSystem(state, uuidRefSystemGps, "GPS", "GPS", "GPS", ReferenceSystem.GOOGLE_EARTH().getVocabulary());
311
			return ReferenceSystem.WGS84(); 
312
		}else if(geoCodeMethod.startsWith("Google")){
313
			return ReferenceSystem.GOOGLE_EARTH();
314
		}else if(geoCodeMethod.startsWith("Map")){
315
			logger.warn("Reference system " +  geoCodeMethod +  " not yet supported.");
316
			return null;
317
		}else if(geoCodeMethod.startsWith("WikiProjekt Georeferenzierung") || geoCodeMethod.startsWith("http://toolserver.org/~geohack/geohack.php") ){
318
			return ReferenceSystem.WGS84();
319
		}else {
320
			logger.warn("Reference system " +  geoCodeMethod +  " not yet supported.");
321
			return null;
322
		}
323
	}
324
	
325

  
326
	
327

  
328
	private void handleCollectorTeam(AlgaTerraImportState state, DerivedUnitFacade facade, ResultSet rs) throws SQLException {
329
		// FIXME parsen
330
		String collector = rs.getString("Collector");
331
		Team team = Team.NewTitledInstance(collector, collector);
332
		facade.setCollector(team);
333
	}
334

  
335
	
336

  
337

  
338
}
app-import/src/main/java/eu/etaxonomy/cdm/io/algaterra/AlgaTerraTypeImport.java
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.ResultSet;
13
import java.sql.SQLException;
14
import java.util.HashMap;
15
import java.util.HashSet;
16
import java.util.Map;
17
import java.util.Set;
18

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

  
23
import eu.etaxonomy.cdm.api.facade.DerivedUnitFacade;
24
import eu.etaxonomy.cdm.api.facade.DerivedUnitFacade.DerivedUnitType;
25
import eu.etaxonomy.cdm.api.facade.DerivedUnitFacadeNotSupportedException;
26
import eu.etaxonomy.cdm.io.algaterra.validation.AlgaTerraTypeImportValidator;
27
import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportConfigurator;
28
import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportState;
29
import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelReferenceImport;
30
import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelTaxonNameImport;
31
import eu.etaxonomy.cdm.io.common.IOValidator;
32
import eu.etaxonomy.cdm.io.common.ResultSetPartitioner;
33
import eu.etaxonomy.cdm.model.common.CdmBase;
34
import eu.etaxonomy.cdm.model.name.BotanicalName;
35
import eu.etaxonomy.cdm.model.name.Rank;
36
import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;
37
import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignationStatus;
38
import eu.etaxonomy.cdm.model.name.TaxonNameBase;
39
import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
40
import eu.etaxonomy.cdm.model.occurrence.FieldObservation;
41
import eu.etaxonomy.cdm.model.reference.Reference;
42

  
43

  
44
/**
45
 * @author a.mueller
46
 * @created 20.03.2008
47
 * @version 1.0
48
 */
49
@Component
50
public class AlgaTerraTypeImport  extends AlgaTerraSpecimenImportBase {
51
	private static final Logger logger = Logger.getLogger(AlgaTerraTypeImport.class);
52

  
53
	
54
	private static int modCount = 5000;
55
	private static final String pluralString = "types";
56
	private static final String dbTableName = "TypeDesignation";  //??  
57

  
58
	protected String getLocalityString(){
59
		return "TypeLocality";
60
	}
61
	
62
	public AlgaTerraTypeImport(){
63
		super();
64
	}
65
	
66
	
67
	/* (non-Javadoc)
68
	 * @see eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportBase#getIdQuery()
69
	 */
70
	@Override
71
	protected String getIdQuery(BerlinModelImportState state) {
72
		String result = " SELECT TypeDesignationId "  
73
				+ " FROM TypeDesignation " 
74
				+ " ORDER BY NameFk ";
75
		return result;
76
	}
77

  
78
	/* (non-Javadoc)
79
	 * @see eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportBase#getRecordQuery(eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportConfigurator)
80
	 */
81
	@Override
82
	protected String getRecordQuery(BerlinModelImportConfigurator config) {
83
			String strQuery =    
84
					
85
			" SELECT ts.*, td.*, gz.ID as GazetteerId, gz.L2Code, gz.L3Code, gz.L4Code, gz.ISOCountry, gz.Country, ts.WaterBody " + 
86
               " " +
87
            " FROM TypeSpecimenDesignation tsd  " 
88
            	+ " LEFT OUTER JOIN TypeSpecimen AS ts ON tsd.TypeSpecimenFk = ts.TypeSpecimenId " 
89
            	+ " FULL OUTER JOIN TypeDesignation td ON  td.TypeDesignationId = tsd.TypeDesignationFk "
90
            	+ " LEFT OUTER JOIN TDWGGazetteer gz ON ts.TDWGGazetteerFk = gz.ID "
91
		+ 	" WHERE (td.TypeDesignationId IN (" + ID_LIST_TOKEN + ")  )"  
92
          + " ORDER BY NameFk "
93
            ;
94
		return strQuery;
95
	}
96

  
97
	/* (non-Javadoc)
98
	 * @see eu.etaxonomy.cdm.io.berlinModel.in.IPartitionedIO#doPartition(eu.etaxonomy.cdm.io.berlinModel.in.ResultSetPartitioner, eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportState)
99
	 */
100
	public boolean doPartition(ResultSetPartitioner partitioner, BerlinModelImportState bmState) {
101
		boolean success = true;
102
		
103
		AlgaTerraImportState state = (AlgaTerraImportState)bmState;
104
		
105
		//TODO check that no duplicate vocabularies will be created, also remove redundant code here
106
//		and in Specimen importer
107
		try {
108
			makeVocabulariesAndFeatures(state);
109
		} catch (SQLException e1) {
110
			logger.warn("Exception occurred when trying to create Type specimen vocabularies: " + e1.getMessage());
111
			e1.printStackTrace();
112
		}
113
		
114
		
115
		
116
		Set<TaxonNameBase> namesToSave = new HashSet<TaxonNameBase>();
117
		
118
		Map<String, TaxonNameBase> taxonNameMap = (Map<String, TaxonNameBase>) partitioner.getObjectMap(BerlinModelTaxonNameImport.NAMESPACE);
119
		Map<String, DerivedUnit> ecoFactMap = (Map<String, DerivedUnit>) partitioner.getObjectMap(AlgaTerraSpecimenImport.ECO_FACT_NAMESPACE);
120
		Map<String, DerivedUnit> typeSpecimenMap = (Map<String, DerivedUnit>) partitioner.getObjectMap(TYPE_SPECIMEN_NAMESPACE);
121
		Map<String, Reference> biblioReference = (Map<String, Reference>) partitioner.getObjectMap(BerlinModelReferenceImport.BIBLIO_REFERENCE_NAMESPACE);
122
		
123
		
124
		ResultSet rs = partitioner.getResultSet();
125

  
126
		try {
127
			
128
			int i = 0;
129

  
130
			//for each reference
131
            while (rs.next()){
132
                
133
        		if ((i++ % modCount) == 0 && i!= 1 ){ logger.info("Type designations handled: " + (i-1));}
134
				
135
				int nameId = rs.getInt("nameFk");
136
				int typeSpecimenId = rs.getInt("TypeSpecimenId");
137
				int typeDesignationId = rs.getInt("TypeDesignationId");
138
				Integer typeStatusFk =  nullSafeInt(rs, "typeStatusFk");
139
				Integer ecoFactId = nullSafeInt(rs, "ecoFactFk");
140
//				String recordBasis = rs.getString("RecordBasis");
141
				
142
				try {
143
					
144
					//source ref
145
					Reference<?> sourceRef = state.getTransactionalSourceReference();
146
				
147
					//facade
148
					//FIXME - depends on material category
149
//					DerivedUnitType type = makeDerivedUnitType(recordBasis);
150
					DerivedUnitType type = DerivedUnitType.Specimen;
151
					DerivedUnitFacade facade = getDerivedUnit(state, typeSpecimenId, typeSpecimenMap, type, ecoFactMap, ecoFactId);
152
					
153
					//field observation
154
					handleSingleSpecimen(rs, facade, state);
155
					
156
					handleTypeSpecimenSpecificSpecimen(rs,facade, state);
157
					
158
					state.setCurrentFieldObservationNotNew(false);
159
					
160
					//Designation
161
					TaxonNameBase<?,?> name = getTaxonName(state, taxonNameMap, nameId);
162
					SpecimenTypeDesignation designation = SpecimenTypeDesignation.NewInstance();
163
					SpecimenTypeDesignationStatus status = getSpecimenTypeDesignationStatusByKey(typeStatusFk);
164
					designation.setTypeSpecimen(facade.innerDerivedUnit());
165
					designation.setTypeStatus(status);
166
					if (name != null){
167
						name.addTypeDesignation(designation, true); //TODO check if true is correct
168
					}else{
169
						logger.warn("Name could not be found for type designation " + typeDesignationId);
170
					}
171
					namesToSave.add(name); 
172
					
173

  
174
				} catch (Exception e) {
175
					logger.warn("Exception in TypeDesignation: TypeDesignationId " + typeDesignationId + ". " + e.getMessage());
176
					e.printStackTrace();
177
				} 
178
                
179
            }
180
           
181
//            logger.warn("Specimen: " + countSpecimen + ", Descriptions: " + countDescriptions );
182

  
183
			logger.warn("Names to save: " + namesToSave.size());
184
			getNameService().save(namesToSave);	
185
			
186
			return success;
187
		} catch (SQLException e) {
188
			logger.error("SQLException:" +  e);
189
			return false;
190
		}
191
	}
192

  
193
	/**
194
	 * @param state 
195
	 * @param taxonNameMap
196
	 * @param nameId
197
	 * @return
198
	 */
199
	private TaxonNameBase getTaxonName(AlgaTerraImportState state, Map<String, TaxonNameBase> taxonNameMap, int nameId) {
200
		TaxonNameBase result;
201
		if (state.getConfig().isDoTaxonNames()){
202
			result = taxonNameMap.get(String.valueOf(nameId));
203
		}else{
204
			//for testing
205
			result = BotanicalName.NewInstance(Rank.SPECIES());
206
		}
207
		return result;
208
	}
209

  
210
	private void handleTypeSpecimenSpecificSpecimen(ResultSet rs, DerivedUnitFacade facade, AlgaTerraImportState state) throws SQLException {
211
		//TODO
212
		
213
		
214
		//collection
215
		String barcode = rs.getString("Barcode");
216
		if (StringUtils.isNotBlank(barcode)){
217
			facade.setBarcode(barcode);
218
		}
219
		
220
	}
221

  
222
	/**
223
	 * @param state
224
	 * @param ecoFactId
225
	 * @param derivedUnitMap
226
	 * @param type 
227
	 * @param ecoFactId2 
228
	 * @param ecoFactMap 
229
	 * @return
230
	 */
231
	private DerivedUnitFacade getDerivedUnit(AlgaTerraImportState state, int typeSpecimenId, Map<String, DerivedUnit> typeSpecimenMap, DerivedUnitType type, Map<String, DerivedUnit> ecoFactMap, Integer ecoFactId2) {
232
		//TODO implement ecoFact map - if not all null anymore
233
		String typeKey = String.valueOf(typeSpecimenId);
234
		DerivedUnit derivedUnit = typeSpecimenMap.get(typeKey);
235
		DerivedUnitFacade facade;
236
		if (derivedUnit == null){
237
			facade = DerivedUnitFacade.NewInstance(type);
238
			typeSpecimenMap.put(typeKey, derivedUnit);
239
		}else{
240
			try {
241
				facade = DerivedUnitFacade.NewInstance(derivedUnit);
242
			} catch (DerivedUnitFacadeNotSupportedException e) {
243
				logger.error(e.getMessage());
244
				facade = DerivedUnitFacade.NewInstance(type);
245
			}
246
		}
247
		
248
		return facade;
249
	}
250
	private DerivedUnitType makeDerivedUnitType(String recordBasis) {
251
		DerivedUnitType result = null;
252
		if (StringUtils.isBlank(recordBasis)){
253
			result = DerivedUnitType.DerivedUnit;
254
		} else if (recordBasis.equalsIgnoreCase("FossileSpecimen")){
255
			result = DerivedUnitType.Fossil;
256
		}else if (recordBasis.equalsIgnoreCase("HumanObservation")){
257
			result = DerivedUnitType.Observation;
258
		}else if (recordBasis.equalsIgnoreCase("Literature")){
259
			logger.warn("Literature record basis not yet supported");
260
			result = DerivedUnitType.DerivedUnit;
261
		}else if (recordBasis.equalsIgnoreCase("LivingSpecimen")){
262
			result = DerivedUnitType.LivingBeing;
263
		}else if (recordBasis.equalsIgnoreCase("MachineObservation")){
264
			logger.warn("MachineObservation record basis not yet supported");
265
			result = DerivedUnitType.Observation;
266
		}else if (recordBasis.equalsIgnoreCase("PreservedSpecimen")){
267
			result = DerivedUnitType.Specimen;
268
		}
269
		return result;
270
	}
271

  
272
	
273
	private SpecimenTypeDesignationStatus getSpecimenTypeDesignationStatusByKey(Integer typeStatusFk) {
274
		if (typeStatusFk == null){ return null;
275
		}else if (typeStatusFk == 1) { return SpecimenTypeDesignationStatus.HOLOTYPE();
276
		}else if (typeStatusFk == 2) { return SpecimenTypeDesignationStatus.LECTOTYPE();
277
		}else if (typeStatusFk == 3) { return SpecimenTypeDesignationStatus.NEOTYPE();
278
		}else if (typeStatusFk == 4) { return SpecimenTypeDesignationStatus.EPITYPE();
279
		}else if (typeStatusFk == 5) { return SpecimenTypeDesignationStatus.ISOLECTOTYPE();
280
		}else if (typeStatusFk == 6) { return SpecimenTypeDesignationStatus.ISONEOTYPE();
281
		}else if (typeStatusFk == 7) { return SpecimenTypeDesignationStatus.ISOTYPE();
282
		}else if (typeStatusFk == 8) { return SpecimenTypeDesignationStatus.PARANEOTYPE();
283
		}else if (typeStatusFk == 9) { return SpecimenTypeDesignationStatus.PARATYPE();
284
		}else if (typeStatusFk == 10) { return SpecimenTypeDesignationStatus.SECOND_STEP_LECTOTYPE();
285
		}else if (typeStatusFk == 11) { return SpecimenTypeDesignationStatus.SECOND_STEP_NEOTYPE();
286
		}else if (typeStatusFk == 12) { return SpecimenTypeDesignationStatus.SYNTYPE();
287
		}else if (typeStatusFk == 13) { return SpecimenTypeDesignationStatus.PARALECTOTYPE();
288
		}else if (typeStatusFk == 14) { return SpecimenTypeDesignationStatus.ISOEPITYPE();
289
		}else if (typeStatusFk == 21) { return SpecimenTypeDesignationStatus.ICONOTYPE();
290
		}else if (typeStatusFk == 22) { return SpecimenTypeDesignationStatus.PHOTOTYPE();
291
		}else if (typeStatusFk == 30) { return SpecimenTypeDesignationStatus.TYPE();
292
		}else if (typeStatusFk == 38) { return SpecimenTypeDesignationStatus.ISOEPITYPE();
293
//		}else if (typeStatusFk == 39) { return SpecimenTypeDesignationStatus.;
294
		}else if (typeStatusFk == 40) { return SpecimenTypeDesignationStatus.ORIGINAL_MATERIAL();
295
		}else{
296
			logger.warn("typeStatusFk undefined for " +  typeStatusFk);
297
			return SpecimenTypeDesignationStatus.TYPE();
298
		}
299
		
300
	}
301

  
302
	
303
	/* (non-Javadoc)
304
	 * @see eu.etaxonomy.cdm.io.berlinModel.in.IPartitionedIO#getRelatedObjectsForPartition(java.sql.ResultSet)
305
	 */
306
	public Map<Object, Map<String, ? extends CdmBase>> getRelatedObjectsForPartition(ResultSet rs) {
307
		String nameSpace;
308
		Class cdmClass;
309
		Set<String> idSet;
310
		Map<Object, Map<String, ? extends CdmBase>> result = new HashMap<Object, Map<String, ? extends CdmBase>>();
311
		
312
		try{
313
			Set<String> nameIdSet = new HashSet<String>();
314
			Set<String> ecoFieldObservationIdSet = new HashSet<String>();
315
			Set<String> typeSpecimenIdSet = new HashSet<String>();
316
			Set<String> termsIdSet = new HashSet<String>();
317
			
318
			while (rs.next()){
319
				handleForeignKey(rs, nameIdSet, "nameFk");
320
				handleForeignKey(rs, ecoFieldObservationIdSet, "ecoFactFk");
321
				handleForeignKey(rs, typeSpecimenIdSet, "TypeSpecimenId");
322
			}
323
			
324
			//name map
325
			nameSpace = BerlinModelTaxonNameImport.NAMESPACE;
326
			cdmClass = TaxonNameBase.class;
327
			idSet = nameIdSet;
328
			Map<String, TaxonNameBase> objectMap = (Map<String, TaxonNameBase>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
329
			result.put(nameSpace, objectMap);
330

  
331
			//eco fact field observation map
332
			nameSpace = AlgaTerraTypeImport.ECO_FACT_NAMESPACE;
333
			cdmClass = FieldObservation.class;
334
			idSet = ecoFieldObservationIdSet;
335
			Map<String, FieldObservation> fieldObservationMap = (Map<String, FieldObservation>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
336
			result.put(nameSpace, fieldObservationMap);
337

  
338
			//type specimen map
339
			nameSpace = AlgaTerraTypeImport.TYPE_SPECIMEN_NAMESPACE;
340
			cdmClass = FieldObservation.class;
341
			idSet = typeSpecimenIdSet;
342
			Map<String, FieldObservation> typeSpecimenMap = (Map<String, FieldObservation>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
343
			result.put(nameSpace, typeSpecimenMap);
344

  
345
			
346
			//
347
//			//terms
348
//			nameSpace = AlgaTerraTypeImport.TERMS_NAMESPACE;
349
//			cdmClass = FieldObservation.class;
350
//			idSet = taxonIdSet;
351
//			Map<String, DefinedTermBase> termMap = (Map<String, DefinedTermBase>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
352
//			result.put(nameSpace, termMap);
353

  
354
		
355
			
356
			
357
		} catch (SQLException e) {
358
			throw new RuntimeException(e);
359
		}
360
		return result;
361
	}
362

  
363

  
364
	
365

  
366
	/* (non-Javadoc)
367
	 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doCheck(eu.etaxonomy.cdm.io.common.IoStateBase)
368
	 */
369
	@Override
370
	protected boolean doCheck(BerlinModelImportState state){
371
		IOValidator<BerlinModelImportState> validator = new AlgaTerraTypeImportValidator();
372
		return validator.validate(state);
373
	}
374
	
375
	/* (non-Javadoc)
376
	 * @see eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportBase#getTableName()
377
	 */
378
	@Override
379
	protected String getTableName() {
380
		return dbTableName;
381
	}
382
	
383
	/* (non-Javadoc)
384
	 * @see eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportBase#getPluralString()
385
	 */
386
	@Override
387
	public String getPluralString() {
388
		return pluralString;
389
	}
390

  
391
	/* (non-Javadoc)
392
	 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#isIgnore(eu.etaxonomy.cdm.io.common.IImportConfigurator)
393
	 */
394
	protected boolean isIgnore(BerlinModelImportState state){
395
		return ! state.getConfig().isDoTypes();
396
	}
397
	
398
}
app-import/src/main/java/eu/etaxonomy/cdm/io/algaterra/validation/AlgaTerraSpecimenImportValidator.java
10 10

  
11 11
package eu.etaxonomy.cdm.io.algaterra.validation;
12 12

  
13
import java.sql.ResultSet;
14
import java.sql.SQLException;
15

  
16
import org.apache.commons.lang.StringUtils;
17 13
import org.apache.log4j.Logger;
18 14

  
19 15
import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportConfigurator;
20 16
import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportState;
21 17
import eu.etaxonomy.cdm.io.common.IOValidator;
22
import eu.etaxonomy.cdm.io.common.Source;
23 18

  
24 19
/**
25 20
 * @author a.mueller
app-import/src/main/java/eu/etaxonomy/cdm/io/algaterra/validation/AlgaTerraTypeImportValidator.java
1
// $Id$
2
/**
3
* Copyright (C) 2007 EDIT
4
* European Distributed Institute of Taxonomy 
5
* http://www.e-taxonomy.eu
6
* 
7
* The contents of this file are subject to the Mozilla Public License Version 1.1
8
* See LICENSE.TXT at the top of this package for the full license terms.
9
*/
10

  
11
package eu.etaxonomy.cdm.io.algaterra.validation;
12

  
13
import java.sql.ResultSet;
14
import java.sql.SQLException;
15

  
16
import org.apache.commons.lang.StringUtils;
17
import org.apache.log4j.Logger;
18

  
19
import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportConfigurator;
20
import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportState;
21
import eu.etaxonomy.cdm.io.common.IOValidator;
22
import eu.etaxonomy.cdm.io.common.Source;
23

  
24
/**
25
 * @author a.mueller
26
 * @created 17.02.2010
27
 * @version 1.0
28
 */
29
public class AlgaTerraTypeImportValidator implements IOValidator<BerlinModelImportState> {
30
	private static final Logger logger = Logger.getLogger(AlgaTerraTypeImportValidator.class);
31

  
32
	/* (non-Javadoc)
33
	 * @see eu.etaxonomy.cdm.io.common.IOValidator#validate(eu.etaxonomy.cdm.io.common.IoStateBase)
34
	 */
35
	public boolean validate(BerlinModelImportState state) {
36
		boolean result = true;
37
		BerlinModelImportConfigurator bmiConfig = state.getConfig();
38
		result &= checkMultipleEntriesInTypeSpecimenDesignation(bmiConfig);
39
		//result &= checkPartOfJournal(bmiConfig);
40
		System.out.println("Checking for Specimen not yet fully implemented");
41
		return result;
42
	}
43
	
44
	
45
	//******************************** CHECK *************************************************
46
		
47
		private static boolean checkMultipleEntriesInTypeSpecimenDesignation(BerlinModelImportConfigurator config){
48
			try {
49
				boolean result = true;
50
				Source source = config.getSource();
51
				String strQuery = " SELECT COUNT(*) AS n, TypeSpecimenFk " +
52
							" FROM TypeSpecimenDesignation " +
53
							" GROUP BY TypeSpecimenFk " +
54
							" HAVING (COUNT(*) > 1)  ";
55

  
56
				ResultSet resulSet = source.getResultSet(strQuery);
57
				if (resulSet.next()){
58
					System.out.println("========================================================");
59
					System.out.println("There are multiple TypeSpecimenDesignations sharing the same TypeSpecimen!");
60
					System.out.println("This is not supported by the current import and will lead to duplicates!");
61
					System.out.println("========================================================");
62
					result = false;
63
				}
64

  
65
				strQuery = " SELECT COUNT(*) AS n, TypeDesignationFk " +
66
						" FROM TypeSpecimenDesignation " +
67
						" GROUP BY TypeDesignationFk " +
68
						" HAVING (COUNT(*) > 1)  ";
69

  
70
				resulSet = source.getResultSet(strQuery);
71
				if (resulSet.next()){
72
					System.out.println("========================================================");
73
					System.out.println("There are multiple TypeSpecimenDesignations sharing the same TypeDesignation!");
74
					System.out.println("This is not supported by the current import and will lead to duplicates!");
75
					System.out.println("========================================================");
76
					result = false;
77
				}
78

  
79
				
80
				return result;
81
			} catch (SQLException e) {
82
				e.printStackTrace();
83
				return false;
84
			}
85
		}
86

  
87
}

Also available in: Unified diff