Project

General

Profile

Download (14.5 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.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.ResultSetPartitioner;
26
import eu.etaxonomy.cdm.io.common.Source;
27
import eu.etaxonomy.cdm.model.agent.Team;
28
import eu.etaxonomy.cdm.model.common.OrderedTermVocabulary;
29
import eu.etaxonomy.cdm.model.common.TimePeriod;
30
import eu.etaxonomy.cdm.model.description.DescriptionBase;
31
import eu.etaxonomy.cdm.model.description.Feature;
32
import eu.etaxonomy.cdm.model.description.SpecimenDescription;
33
import eu.etaxonomy.cdm.model.description.State;
34
import eu.etaxonomy.cdm.model.location.NamedArea;
35
import eu.etaxonomy.cdm.model.location.Point;
36
import eu.etaxonomy.cdm.model.location.ReferenceSystem;
37
import eu.etaxonomy.cdm.model.location.TdwgArea;
38
import eu.etaxonomy.cdm.model.location.WaterbodyOrCountry;
39
import eu.etaxonomy.cdm.model.occurrence.Collection;
40

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

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

    
77

    
78
	/**
79
	 * Creates the vocabularies and the features for Climate, Habitat and Lifeform
80
	 * @param state
81
	 * @throws SQLException
82
	 */
83
	protected void makeVocabulariesAndFeatures(AlgaTerraImportState state) throws SQLException {
84
		String abbrevLabel = null;
85
		URI uri = null;
86
		
87
		if (! state.isSpecimenVocabulariesCreated()){
88
			
89
			TransactionStatus txStatus = this.startTransaction();
90
		
91
			boolean isOrdered = true;
92
			OrderedTermVocabulary<State> climateVoc = (OrderedTermVocabulary)getVocabulary(uuidVocAlgaTerraClimate, "Climate", "Climate", abbrevLabel, uri, isOrdered, null);
93
			OrderedTermVocabulary<State> habitatVoc = (OrderedTermVocabulary)getVocabulary(uuidVocAlgaTerraHabitat, "Habitat", "Habitat", abbrevLabel, uri, isOrdered, null);
94
			OrderedTermVocabulary<State> lifeformVoc = (OrderedTermVocabulary)getVocabulary(uuidVocAlgaTerraLifeForm, "Lifeform", "Lifeform", abbrevLabel, uri, isOrdered, null);
95
			
96
			
97
			Feature feature = getFeature(state, uuidFeatureAlgaTerraClimate, "Climate","Climate", null, null);
98
			feature.setSupportsCategoricalData(true);
99
			
100
			feature = getFeature(state, uuidFeatureAlgaTerraLifeForm, "LifeForm","LifeForm", null, null);
101
			feature.setSupportsCategoricalData(true);
102
			
103
			feature = Feature.HABITAT();
104
			feature.setSupportsCategoricalData(true);
105
			getTermService().saveOrUpdate(feature);
106
			
107
			Source source = state.getAlgaTerraConfigurator().getSource();
108
			
109
			String climateSql = "SELECT * FROM EcoClimate";
110
			ResultSet rs = source.getResultSet(climateSql);
111
			while (rs.next()){
112
				String climate = rs.getString("Climate");
113
				String description = rs.getString("Description");
114
				Integer id = rs.getInt("ClimateId");
115
				UUID uuid = UUID.fromString(rs.getString("UUID"));
116
				State stateTerm = getStateTerm(state, uuid, climate, description, null, climateVoc);
117
				addOriginalSource(stateTerm, id.toString(), "EcoClimate", state.getTransactionalSourceReference());
118
				getTermService().saveOrUpdate(stateTerm);
119
			}
120
			
121
			String habitatSql = "SELECT * FROM EcoHabitat";
122
			rs = source.getResultSet(habitatSql);
123
			while (rs.next()){
124
				String habitat = rs.getString("Habitat");
125
				String description = rs.getString("Description");
126
				Integer id = rs.getInt("HabitatId");
127
				UUID uuid = UUID.fromString(rs.getString("UUID"));
128
				State stateTerm = getStateTerm(state, uuid, habitat, description, null, habitatVoc);
129
				addOriginalSource(stateTerm, id.toString(), "EcoHabitat", state.getTransactionalSourceReference());
130
				getTermService().saveOrUpdate(stateTerm);
131
			}
132
			
133
			String lifeformSql = "SELECT * FROM EcoLifeForm";
134
			rs = source.getResultSet(lifeformSql);
135
			while (rs.next()){
136
				String lifeform = rs.getString("LifeForm");
137
				String description = rs.getString("Description");
138
				Integer id = rs.getInt("LifeFormId");
139
				UUID uuid = UUID.fromString(rs.getString("UUID"));
140
				State stateTerm = getStateTerm(state, uuid, lifeform, description, null, lifeformVoc);
141
				addOriginalSource(stateTerm, id.toString(), "EcoLifeForm", state.getTransactionalSourceReference());
142
				getTermService().saveOrUpdate(stateTerm);
143
			}
144
			
145
			this.commitTransaction(txStatus);
146
			
147
			state.setSpecimenVocabulariesCreated(true);
148
		}
149
		
150
	}
151
	
152
	protected String getLocalityString(){
153
		return "Locality";
154
	}
155
	
156
	protected void handleSingleSpecimen(ResultSet rs, DerivedUnitFacade facade, AlgaTerraImportState state, ResultSetPartitioner partitioner) throws SQLException {
157
		//FIXME missing fields #3084, #3085, #3080
158
		try {
159
			
160
			Integer unitId = nullSafeInt(rs, "unitId");
161
			String locality = rs.getString(getLocalityString());
162
			Double latitude = nullSafeDouble(rs, "Latitude");
163
			Double longitude = nullSafeDouble(rs, "Longitude");
164
			Integer errorRadius = nullSafeInt(rs,"Prec");
165
			String geoCodeMethod = rs.getString("GeoCodeMethod");
166
			
167
			Integer altitude = nullSafeInt(rs, "Altitude");
168
			Integer lowerAltitude = nullSafeInt(rs,"AltitudeLowerValue");
169
			String altitudeUnit = rs.getString("AltitudeUnit");
170
			Double depth = nullSafeDouble(rs, "Depth");
171
			Double depthLow = nullSafeDouble(rs, "DepthLow");
172
			   	
173
			String collectorsNumber = rs.getString("CollectorsNumber");
174
			Date collectionDateStart = rs.getDate("CollectionDate");
175
			Date collectionDateEnd = rs.getDate("CollectionDateEnd");
176
			
177
			Integer collectionFk = nullSafeInt(rs,"CollectionFk");
178
			
179
			
180
			//location
181
			facade.setLocality(locality);
182
			    	
183
			//exact location
184
			ReferenceSystem referenceSystem = makeRefrenceSystem(geoCodeMethod, state);
185
			if (longitude != null || latitude != null || referenceSystem != null || errorRadius != null){
186
				Point exactLocation = Point.NewInstance(longitude, latitude, referenceSystem, errorRadius);
187
				facade.setExactLocation(exactLocation);
188
			}
189
			
190
			//altitude, depth
191
			if (StringUtils.isNotBlank(altitudeUnit) && ! altitudeUnit.trim().equalsIgnoreCase("m")){
192
				logger.warn("Altitude unit is not [m] but: " +  altitudeUnit);
193
			}
194
			if ( altitude != null){
195
				if (lowerAltitude == null){
196
					facade.setAbsoluteElevation(altitude);
197
				}else{
198
			   		if (! facade.isEvenDistance(lowerAltitude, altitude)){
199
			   			//FIXME there is a ticket for this
200
			   			altitude = altitude + 1;
201
			   			logger.info("Current implementation of altitude does not allow uneven distances");
202
			   		}
203
					facade.setAbsoluteElevationRange(lowerAltitude,altitude);
204
			   	}
205
			}
206
			if ( depth != null){
207
				//FIXME needs model change to accept double #3072
208
				Integer intDepth = depth.intValue();
209
				if (depthLow == null){
210
					facade.setDistanceToWaterSurface(intDepth);
211
				}else{
212
					//FIXME range not yet in model #3074
213
			   		facade.setDistanceToWaterSurface(intDepth);
214
			   	}
215
			}
216
			
217
			//field
218
			facade.setFieldNumber(collectorsNumber);
219
			TimePeriod gatheringPeriod = TimePeriod.NewInstance(collectionDateStart, collectionDateEnd);
220
			facade.setGatheringPeriod(gatheringPeriod);
221
			handleCollectorTeam(state, facade, rs);
222
			
223
			//areas
224
			makeAreas(state, rs, facade);
225
			
226
			//collection
227
			if (collectionFk != null){
228
				Collection subCollection = state.getRelatedObject(AlgaTerraCollectionImport.NAMESPACE_SUBCOLLECTION, String.valueOf(collectionFk), Collection.class);
229
				if (subCollection != null){
230
					facade.setCollection(subCollection);
231
				}else{
232
					Collection collection = state.getRelatedObject(AlgaTerraCollectionImport.NAMESPACE_COLLECTION, String.valueOf(collectionFk), Collection.class);
233
					facade.setCollection(collection);
234
				}
235
			}
236
			
237
			//notes
238
			//TODO is this an annotation on field observation or on the derived unit?
239
			
240
			//TODO id, created for fact +  ecoFact
241
			//    	this.doIdCreatedUpdatedNotes(state, descriptionElement, rs, id, namespace);
242
			if (unitId != null){
243
				this.doIdCreatedUpdatedNotes(state, facade.innerDerivedUnit(), rs, unitId, getDerivedUnitNameSpace());
244
			}else{
245
				logger.warn("Specimen has no unitId: " +  facade.innerDerivedUnit() + ": " + getDerivedUnitNameSpace());
246
			}
247
			
248
			
249
		} catch (Exception e) {
250
			throw new RuntimeException(e);
251
		}
252
    	
253
	}
254
	
255
	protected abstract String getDerivedUnitNameSpace();
256

    
257
	protected DescriptionBase getFieldObservationDescription(DerivedUnitFacade facade) {
258
		Set<DescriptionBase> descriptions = facade.innerFieldObservation().getDescriptions();
259
		for (DescriptionBase desc : descriptions){
260
			if (desc.isImageGallery() == false){
261
				return desc;
262
			}
263
		}
264
		SpecimenDescription specDesc = SpecimenDescription.NewInstance(facade.innerFieldObservation());
265
		descriptions.add(specDesc);
266
		return specDesc;
267
	}
268
	
269

    
270
	private void makeAreas(AlgaTerraImportState state, ResultSet rs, DerivedUnitFacade facade) throws SQLException {
271
	   	Object gazetteerId = rs.getObject("GazetteerId");
272
	   	if (gazetteerId != null){
273
	   		//TDWG
274
	   		NamedArea tdwgArea;
275
	   		String tdwg4 = rs.getString("L4Code");
276
	   		if (isNotBlank(tdwg4)){
277
	   			tdwgArea = TdwgArea.getAreaByTdwgAbbreviation(tdwg4);
278
	   		}else{
279
	   			String tdwg3 = rs.getString("L3Code");
280
	   			if (isNotBlank(tdwg3)){
281
	   				tdwgArea = TdwgArea.getAreaByTdwgAbbreviation(tdwg3);
282
	   			}else{
283
	   				Integer tdwg2 = rs.getInt("L2Code");   				
284
	   				tdwgArea = TdwgArea.getAreaByTdwgAbbreviation(String.valueOf(tdwg2));
285
		   		}
286
	   		}
287
	   		if (tdwgArea == null){
288
	   			logger.warn("TDWG area could not be defined for gazetterId: " + gazetteerId);
289
	   		}else{
290
	   			facade.addCollectingArea(tdwgArea);
291
	   		}
292
	   		
293
	   		//Countries
294
	   		WaterbodyOrCountry country = null;
295
	   		String isoCountry = rs.getString("ISOCountry");
296
	   		String countryStr = rs.getString("Country");
297
	   		if (isNotBlank(isoCountry)){
298
		   		country = WaterbodyOrCountry.getWaterbodyOrCountryByIso3166A2(isoCountry);
299
	   		}else if (isNotBlank(countryStr)){
300
	   			logger.warn("Country exists but no ISO code");
301
	   		}
302
	   		if (country == null){
303
	   			logger.warn("Country does not exist for GazetteerID " + gazetteerId);
304
	   		}else{
305
	   			facade.setCountry(country);
306
	   		}
307
	   		
308
	   	}
309
	    
310
	   	//Waterbody
311
	   	WaterbodyOrCountry waterbody = null;
312
	   	String waterbodyStr = rs.getString("WaterBody");
313
	   	if (isNotBlank(waterbodyStr)){
314
	   		if (waterbodyStr.equals("Atlantic Ocean")){
315
	   			waterbody = WaterbodyOrCountry.ATLANTICOCEAN();
316
	   		}else{
317
	   			logger.warn("Waterbody not recognized: " + waterbody);
318
	   		}
319
	   		if (waterbody != null){
320
	   			facade.addCollectingArea(waterbody);
321
	   		}
322
	   	}
323

    
324
		
325
	   	//countries sub
326
	   	//TODO -> SpecimenImport (not existing in TypeSpecimen)
327
	}
328

    
329

    
330
	
331

    
332
	private ReferenceSystem makeRefrenceSystem(String geoCodeMethod, AlgaTerraImportState state) {
333
		if (StringUtils.isBlank(geoCodeMethod)){
334
			return null;
335
		}else if(geoCodeMethod.startsWith("GPS")){
336
			getReferenceSystem(state, uuidRefSystemGps, "GPS", "GPS", "GPS", ReferenceSystem.GOOGLE_EARTH().getVocabulary());
337
			return ReferenceSystem.WGS84(); 
338
		}else if(geoCodeMethod.startsWith("Google")){
339
			return ReferenceSystem.GOOGLE_EARTH();
340
		}else if(geoCodeMethod.startsWith("Map")){
341
			logger.warn("Reference system " +  geoCodeMethod +  " not yet supported.");
342
			return null;
343
		}else if(geoCodeMethod.startsWith("WikiProjekt Georeferenzierung") || geoCodeMethod.startsWith("http://toolserver.org/~geohack/geohack.php") ){
344
			return ReferenceSystem.WGS84();
345
		}else {
346
			logger.warn("Reference system " +  geoCodeMethod +  " not yet supported.");
347
			return null;
348
		}
349
	}
350
	
351

    
352
	
353

    
354
	private void handleCollectorTeam(AlgaTerraImportState state, DerivedUnitFacade facade, ResultSet rs) throws SQLException {
355
		// FIXME parsen
356
		String collector = rs.getString("Collector");
357
		Team team = Team.NewTitledInstance(collector, collector);
358
		facade.setCollector(team);
359
	}
360

    
361
	
362

    
363

    
364
}
(8-8/11)