Project

General

Profile

Download (24 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.HashMap;
17
import java.util.Map;
18
import java.util.Set;
19
import java.util.UUID;
20

    
21
import org.apache.commons.lang.StringUtils;
22
import org.apache.log4j.Logger;
23
import org.springframework.transaction.TransactionStatus;
24

    
25
import eu.etaxonomy.cdm.api.facade.DerivedUnitFacade;
26
import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportBase;
27
import eu.etaxonomy.cdm.io.common.ResultSetPartitioner;
28
import eu.etaxonomy.cdm.io.common.Source;
29
import eu.etaxonomy.cdm.io.common.TdwgAreaProvider;
30
import eu.etaxonomy.cdm.model.agent.Team;
31
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
32
import eu.etaxonomy.cdm.model.common.Annotation;
33
import eu.etaxonomy.cdm.model.common.AnnotationType;
34
import eu.etaxonomy.cdm.model.common.DefinedTerm;
35
import eu.etaxonomy.cdm.model.common.Language;
36
import eu.etaxonomy.cdm.model.common.OrderedTermVocabulary;
37
import eu.etaxonomy.cdm.model.common.TermType;
38
import eu.etaxonomy.cdm.model.common.TermVocabulary;
39
import eu.etaxonomy.cdm.model.common.TimePeriod;
40
import eu.etaxonomy.cdm.model.description.DescriptionBase;
41
import eu.etaxonomy.cdm.model.description.Feature;
42
import eu.etaxonomy.cdm.model.description.SpecimenDescription;
43
import eu.etaxonomy.cdm.model.description.State;
44
import eu.etaxonomy.cdm.model.description.TaxonDescription;
45
import eu.etaxonomy.cdm.model.location.Country;
46
import eu.etaxonomy.cdm.model.location.NamedArea;
47
import eu.etaxonomy.cdm.model.location.Point;
48
import eu.etaxonomy.cdm.model.location.ReferenceSystem;
49
import eu.etaxonomy.cdm.model.occurrence.Collection;
50
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationType;
51
import eu.etaxonomy.cdm.model.reference.Reference;
52
import eu.etaxonomy.cdm.model.taxon.Taxon;
53

    
54
/**
55
 * @author a.mueller
56
 * @created 12.09.2012
57
 */
58
public abstract class AlgaTerraSpecimenImportBase extends BerlinModelImportBase{
59
	private static final Logger logger = Logger.getLogger(AlgaTerraSpecimenImportBase.class);
60

    
61
	public static final String ECO_FACT_FIELD_OBSERVATION_NAMESPACE = "EcoFact_FieldObservation";
62
	public static final String ECO_FACT_DERIVED_UNIT_NAMESPACE = "EcoFact_DerivedUnit";
63
	public static final String TYPE_SPECIMEN_FIELD_OBSERVATION_NAMESPACE = "TypeSpecimen_FieldObservation";
64
	public static final String TYPE_SPECIMEN_DERIVED_UNIT_NAMESPACE = "TypeSpecimen_DerivedUnit";
65
	public static final String FACT_ECOLOGY_NAMESPACE = "Fact (Ecology)";
66

    
67

    
68
	public static final String TERMS_NAMESPACE = "ALGA_TERRA_TERMS";
69

    
70
	//TODO move to transformrer
71
	final static UUID uuidMarkerAlkalinity = UUID.fromString("e52d0ea2-0c1f-4d95-ae6d-e21ab317c594");
72
	final static UUID uuidRefSystemGps = UUID.fromString("c23e4928-c137-4e4a-b6ab-b430da3d0b94");
73
	public final static UUID uuidFeatureSpecimenCommunity = UUID.fromString("3ff5b1ab-3999-4b5a-b8f7-01fd2f6c12c7");
74
	public final static UUID uuidFeatureAdditionalData = UUID.fromString("0ac82ab8-2c2b-4953-98eb-a9f718eb9c57");
75
	public final static UUID uuidFeatureHabitatExplanation = UUID.fromString("6fe32295-61a3-44fc-9fcf-a85790ea888f");
76

    
77
	final static UUID uuidVocAlgaTerraClimate = UUID.fromString("b0a677c6-8bb6-43f4-b1b8-fc377a10feb5");
78
	final static UUID uuidVocAlgaTerraHabitat = UUID.fromString("06f30114-e19c-4e7d-a8e5-5488c41fcbc5");
79
	final static UUID uuidVocAlgaTerraLifeForm = UUID.fromString("3c0b194e-809c-4b42-9498-6ff034066ed7");
80

    
81
	public final static UUID uuidFeatureAlgaTerraClimate = UUID.fromString("8754674c-9ab9-4f28-95f1-91eeee2314ee");
82
	public final static UUID uuidFeatureAlgaTerraHabitat = UUID.fromString("7def3fc2-cdc5-4739-8e13-62edbd053415");
83
	public final static UUID uuidFeatureAlgaTerraLifeForm = UUID.fromString("9b657901-1b0d-4a2a-8d21-dd8c1413e2e6");
84

    
85
	final static UUID uuidVocParameter = UUID.fromString("45888b40-5bbb-4293-aa1e-02479796cd7c");
86
	final static UUID uuidStatMeasureSingleValue = UUID.fromString("eb4c3d98-4d4b-4c37-8eb4-17315ce79920");
87
	final static UUID uuidMeasurementValueModifier = UUID.fromString("0218a7a3-f6c0-4d06-a4f8-6b50b73aef5e");
88

    
89
	final static UUID uuidModifierLowerThan = UUID.fromString("2b500085-6bef-4003-b6ea-e0ad0237d79d");
90
	final static UUID uuidModifierGreaterThan = UUID.fromString("828df49d-c745-48f7-b083-0ada43356c34");
91

    
92
	public AlgaTerraSpecimenImportBase(String tableName, String pluralString) {
93
		super(tableName, pluralString);
94
	}
95

    
96
	/**
97
	 * Creates the vocabularies and the features for Climate, Habitat and Lifeform
98
	 * @param state
99
	 * @throws SQLException
100
	 */
101
	protected void makeVocabulariesAndFeatures(AlgaTerraImportState state) throws SQLException {
102
		String abbrevLabel = null;
103
		URI uri = null;
104

    
105
		if (! state.isSpecimenVocabulariesCreated()){
106

    
107
			TransactionStatus txStatus = this.startTransaction();
108

    
109
			boolean isOrdered = true;
110
			State tmp = State.NewInstance();
111
			OrderedTermVocabulary<State> climateVoc = (OrderedTermVocabulary<State>)getVocabulary(TermType.State, uuidVocAlgaTerraClimate, "Climate", "Climate", abbrevLabel, uri, isOrdered, tmp);
112
			OrderedTermVocabulary<State> habitatVoc = (OrderedTermVocabulary<State>)getVocabulary(TermType.State, uuidVocAlgaTerraHabitat, "Habitat", "Habitat", abbrevLabel, uri, isOrdered, tmp);
113
			OrderedTermVocabulary<State> lifeformVoc = (OrderedTermVocabulary<State>)getVocabulary(TermType.State, uuidVocAlgaTerraLifeForm, "Lifeform", "Lifeform", abbrevLabel, uri, isOrdered, tmp);
114

    
115
			Feature feature = getFeature(state, uuidFeatureAlgaTerraClimate, "Climate","Climate", null, null);
116
			feature.setSupportsCategoricalData(true);
117

    
118
			feature = getFeature(state, uuidFeatureAlgaTerraLifeForm, "LifeForm","LifeForm", null, null);
119
			feature.setSupportsCategoricalData(true);
120

    
121
			feature = Feature.HABITAT();
122
			feature.setSupportsCategoricalData(true);
123
			getTermService().saveOrUpdate(feature);
124

    
125
			Source source = state.getAlgaTerraConfigurator().getSource();
126

    
127
			String climateSql = "SELECT * FROM EcoClimate";
128
			ResultSet rs = source.getResultSet(climateSql);
129
			while (rs.next()){
130
				String climate = rs.getString("Climate");
131
				String description = rs.getString("Description");
132
				Integer id = rs.getInt("ClimateId");
133
				UUID uuid = UUID.fromString(rs.getString("UUID"));
134
				State stateTerm = getStateTerm(state, uuid, climate, description, null, climateVoc);
135
				addOriginalSource(stateTerm, id.toString(), "EcoClimate", state.getTransactionalSourceReference());
136
				getTermService().saveOrUpdate(stateTerm);
137
			}
138

    
139
			String habitatSql = "SELECT * FROM EcoHabitat";
140
			rs = source.getResultSet(habitatSql);
141
			while (rs.next()){
142
				String habitat = rs.getString("Habitat");
143
				String description = rs.getString("Description");
144
				Integer id = rs.getInt("HabitatId");
145
				UUID uuid = UUID.fromString(rs.getString("UUID"));
146
				State stateTerm = getStateTerm(state, uuid, habitat, description, null, habitatVoc);
147
				addOriginalSource(stateTerm, id.toString(), "EcoHabitat", state.getTransactionalSourceReference());
148
				getTermService().saveOrUpdate(stateTerm);
149
			}
150

    
151
			String lifeformSql = "SELECT * FROM EcoLifeForm";
152
			rs = source.getResultSet(lifeformSql);
153
			while (rs.next()){
154
				String lifeform = rs.getString("LifeForm");
155
				String description = rs.getString("Description");
156
				Integer id = rs.getInt("LifeFormId");
157
				UUID uuid = UUID.fromString(rs.getString("UUID"));
158
				State stateTerm = getStateTerm(state, uuid, lifeform, description, null, lifeformVoc);
159
				addOriginalSource(stateTerm, id.toString(), "EcoLifeForm", state.getTransactionalSourceReference());
160
				getTermService().saveOrUpdate(stateTerm);
161
			}
162

    
163
			//material category
164
			TermVocabulary<DefinedTerm> materialCategoryVoc = getVocabulary(TermType.KindOfUnit, AlgaTerraImportTransformer.uuidKindOfUnitVoc, "Alga Terra Material Category", "Alga Terra Material Category", abbrevLabel, uri, false, DefinedTerm.NewKindOfUnitInstance(null, null, null));
165
			getVocabularyService().save(materialCategoryVoc);
166

    
167
			String materialSql = "SELECT * FROM MaterialCategory WHERE MaterialCategoryId <> 16 ";
168
			rs = source.getResultSet(materialSql);
169
			while (rs.next()){
170
				Integer id = rs.getInt("MaterialCategoryId");
171
				String category = rs.getString("MaterialCategory");
172
				String description = rs.getString("Description");
173
				UUID uuid = UUID.randomUUID();
174

    
175
				DefinedTerm kindOfUnit = DefinedTerm.NewKindOfUnitInstance(description, category, null);
176
				kindOfUnit.setUuid(uuid);
177
				addOriginalSource(kindOfUnit, id.toString(), "MaterialCategory", state.getTransactionalSourceReference());
178
				materialCategoryVoc.addTerm(kindOfUnit);
179
				getTermService().saveOrUpdate(kindOfUnit);
180
				materialCategoryMapping.put(id, uuid);
181
			}
182

    
183
			//areas
184
			OrderedTermVocabulary<NamedArea> informalAreasVoc = (OrderedTermVocabulary<NamedArea>)getVocabulary(TermType.NamedArea, AlgaTerraImportTransformer.uuidNamedAreaVocAlgaTerraInformalAreas, "AlgaTerra Specific Areas", "AlgaTerra Specific Areas", abbrevLabel, uri, true, NamedArea.NewInstance());
185
			getVocabularyService().save(informalAreasVoc);
186

    
187
			String areaSql = "SELECT * FROM TDWGGazetteer WHERE subL4 = 1 ";
188
			rs = source.getResultSet(areaSql);
189
			while (rs.next()){
190
				String l1Code = rs.getString("L1Code");
191
				String l2Code = rs.getString("L2Code");
192
				String l3Code = rs.getString("L3Code");
193
				String l4Code = rs.getString("L4Code");
194
				String gazetteer = rs.getString("Gazetteer");
195
				Integer id = rs.getInt("ID");
196
				String notes = rs.getString("Notes");
197
				//TODO stable uuids
198
//				UUID uuid = UUID.fromString(rs.getString("UUID"));
199
				UUID uuid = UUID.randomUUID();
200
				subL4Mapping.put(id, uuid);
201

    
202
				String tdwgCode =  (l4Code != null) ? l4Code : (l3Code != null) ? l3Code : (l2Code != null) ? l2Code : l1Code;
203

    
204
				NamedArea tdwgArea = TdwgAreaProvider.getAreaByTdwgAbbreviation(tdwgCode);
205
				NamedArea newArea  = getNamedArea(state, uuid ,gazetteer, gazetteer, null, null, null, informalAreasVoc, TermMatchMode.UUID_ONLY, null);
206
				if (isNotBlank(notes)){
207
					newArea.addAnnotation(Annotation.NewInstance(notes, AnnotationType.EDITORIAL(), Language.DEFAULT()));
208
				}
209

    
210
				addOriginalSource(newArea, id.toString(), "TDWGGazetteer", state.getTransactionalSourceReference());
211
				getTermService().saveOrUpdate(newArea);
212
				newArea.setPartOf(tdwgArea);
213
				informalAreasVoc.addTerm(newArea);
214
			}
215

    
216
			this.commitTransaction(txStatus);
217

    
218
			state.setSpecimenVocabulariesCreated(true);
219
		}
220
	}
221

    
222
	//tmp
223
	static Map<Integer, UUID> subL4Mapping = new HashMap<Integer, UUID>();
224
	static Map<Integer, UUID> materialCategoryMapping = new HashMap<Integer, UUID>();
225

    
226
	protected String getLocalityString(){
227
		return "Locality";
228
	}
229

    
230
	protected void handleFieldObservationSpecimen(ResultSet rs, DerivedUnitFacade facade, AlgaTerraImportState state, ResultSetPartitioner partitioner) throws SQLException {
231
		//FIXME missing fields #3084, #3085, #3080
232
		try {
233

    
234
			Integer unitId = nullSafeInt(rs, "unitId");
235
			String locality = rs.getString(getLocalityString());
236
			Double latitude = nullSafeDouble(rs, "Latitude");
237
			Double longitude = nullSafeDouble(rs, "Longitude");
238
			Integer errorRadius = nullSafeInt(rs,"Prec");
239
			String geoCodeMethod = rs.getString("GeoCodeMethod");
240

    
241
			Integer altitude = nullSafeInt(rs, "Altitude");
242
			Integer lowerAltitude = nullSafeInt(rs, "AltitudeLowerValue");
243
			String altitudeUnit = rs.getString("AltitudeUnit");
244
			Double depth = nullSafeDouble(rs, "Depth");
245
			Double depthLow = nullSafeDouble(rs, "DepthLow");
246

    
247
			String collectorsNumber = rs.getString("CollectorsNumber");
248
			Date collectionDateStart = rs.getDate("CollectionDate");
249
			Date collectionDateEnd = rs.getDate("CollectionDateEnd");
250

    
251
			//location
252
			facade.setLocality(locality);
253

    
254
			//exact location
255
			ReferenceSystem referenceSystem = makeRefrenceSystem(geoCodeMethod, state);
256
			if (longitude != null || latitude != null || referenceSystem != null || errorRadius != null){
257
				Point exactLocation = Point.NewInstance(longitude, latitude, referenceSystem, errorRadius);
258
				facade.setExactLocation(exactLocation);
259
			}
260

    
261
			//altitude, depth
262
			if (StringUtils.isNotBlank(altitudeUnit) && ! altitudeUnit.trim().equalsIgnoreCase("m")){
263
				logger.warn("Altitude unit is not [m] but: " +  altitudeUnit);
264
			}
265
			if ( altitude != null){
266
				if (lowerAltitude == null){
267
					facade.setAbsoluteElevation(altitude);
268
				}else{
269
					facade.setAbsoluteElevationRange(lowerAltitude,altitude);
270
			   	}
271
			}
272
			if ( depth != null){
273
				if (depthLow == null){
274
					facade.setDistanceToWaterSurface(depth);
275
				}else{
276
					//TODO which direction is correct?
277
					facade.setDistanceToWaterSurfaceRange(depth, depthLow);
278
			   	}
279
			}
280

    
281
			//field
282
			facade.setFieldNumber(collectorsNumber);
283
			TimePeriod gatheringPeriod = TimePeriod.NewInstance(collectionDateStart, collectionDateEnd);
284
			facade.setGatheringPeriod(gatheringPeriod);
285
			handleCollectorTeam(state, facade, rs);
286

    
287
			//areas
288
			makeAreas(state, rs, facade);
289

    
290
			//notes
291
			//=> not required according to Henning
292

    
293
			//id, created, updated, notes
294
			if (unitId != null){
295
				this.doIdCreatedUpdatedNotes(state, facade.innerFieldUnit(), rs, unitId, getFieldObservationNameSpace());
296
			}else{
297
				logger.warn("FieldObservation has no unitId: " +  facade.innerFieldUnit() + ": " + getFieldObservationNameSpace());
298
			}
299
		} catch (Exception e) {
300
			throw new RuntimeException(e);
301
		}
302

    
303
	}
304

    
305
	protected void handleFirstDerivedSpecimen(ResultSet rs, DerivedUnitFacade facade, AlgaTerraImportState state, ResultSetPartitioner partitioner) throws SQLException {
306
		Integer unitId = nullSafeInt(rs, "unitId");
307
		Integer collectionFk = nullSafeInt(rs,"CollectionFk");
308
		String label = rs.getString("Label");
309

    
310
		//collection
311
		if (collectionFk != null){
312
			Collection subCollection = state.getRelatedObject(AlgaTerraCollectionImport.NAMESPACE_SUBCOLLECTION, String.valueOf(collectionFk), Collection.class);
313
			if (subCollection != null){
314
				facade.setCollection(subCollection);
315
			}else{
316
				Collection collection = state.getRelatedObject(AlgaTerraCollectionImport.NAMESPACE_COLLECTION, String.valueOf(collectionFk), Collection.class);
317
				if (collection == null){
318
					logger.warn("Collection for collectionFK " + collectionFk + " can not be found.");
319
				}
320
				facade.setCollection(collection);
321
			}
322
		}
323

    
324
		//Label
325
		if (isNotBlank(label)){
326
			//TODO implement label #4218, #3090, #3084
327
			logger.warn("Label not yet implemented for specimen, #4218, #3090, #3084");
328
		}
329

    
330
		//TODO id, created for fact +  ecoFact
331
		//    	this.doIdCreatedUpdatedNotes(state, descriptionElement, rs, id, namespace);
332
		if (unitId != null){
333
			this.doIdCreatedUpdatedNotes(state, facade.innerDerivedUnit(), rs, unitId, getDerivedUnitNameSpace());
334
		}else{
335
			logger.warn("Specimen has no unitId: " +  facade.innerDerivedUnit() + ": " + getDerivedUnitNameSpace());
336
		}
337
	}
338

    
339

    
340

    
341
	protected abstract String getDerivedUnitNameSpace();
342

    
343
	protected abstract String getFieldObservationNameSpace();
344

    
345

    
346
	protected DescriptionBase<?> getFieldObservationDescription(DerivedUnitFacade facade) {
347
		Set<DescriptionBase<?>> descriptions = (Set)facade.innerFieldUnit().getDescriptions();
348
		for (DescriptionBase<?> desc : descriptions){
349
			if (desc.isImageGallery() == false){
350
				return desc;
351
			}
352
		}
353
		SpecimenDescription specDesc = SpecimenDescription.NewInstance(facade.innerFieldUnit());
354
		descriptions.add(specDesc);
355
		return specDesc;
356
	}
357

    
358

    
359
	private void makeAreas(AlgaTerraImportState state, ResultSet rs, DerivedUnitFacade facade) throws SQLException {
360
	   	Integer gazetteerId = nullSafeInt(rs, "GazetteerId");
361
	   	if (gazetteerId != null){
362
	   		//TDWG
363
	   		NamedArea tdwgArea;
364
	   		String tdwg4 = rs.getString("L4Code");
365
	   		if (isNotBlank(tdwg4)){
366
	   			tdwgArea = TdwgAreaProvider.getAreaByTdwgAbbreviation(tdwg4);
367
	   		}else{
368
	   			String tdwg3 = rs.getString("L3Code");
369
	   			if (isNotBlank(tdwg3)){
370
	   				tdwgArea = TdwgAreaProvider.getAreaByTdwgAbbreviation(tdwg3);
371
	   			}else{
372
	   				Number tdwg2D = nullSafeDouble(rs, "L2Code");
373
	   				if (tdwg2D != null){
374
	   					Integer tdwg2 = tdwg2D.intValue();
375
		   				tdwgArea = TdwgAreaProvider.getAreaByTdwgAbbreviation(String.valueOf(tdwg2));
376
	   				}else{
377
	   					Number tdwg1D = nullSafeDouble(rs, "L1Code");
378
		   				if (tdwg1D != null){
379
		   					Integer tdwg1 = tdwg1D.intValue();
380
		   					tdwgArea = TdwgAreaProvider.getAreaByTdwgAbbreviation(String.valueOf(tdwg1));
381
		   				}else{
382
		   					tdwgArea = null;
383
		   				}
384
	   				}
385
		   		}
386
	   		}
387
	   		if (tdwgArea == null){
388
	   			logger.warn("TDWG area could not be defined for gazetterId: " + gazetteerId);
389
	   		}else{
390
	   			facade.addCollectingArea(tdwgArea);
391
	   		}
392

    
393
	   		//Countries
394
	   		Country country = null;
395
	   		String isoCountry = rs.getString("ISOCountry");
396
	   		String countryStr = rs.getString("Country");
397
	   		if (isNotBlank(isoCountry)){
398
		   		country = Country.getCountryByIso3166A2(isoCountry);
399
	   		}else if (isNotBlank(countryStr)){
400
	   			logger.warn("Country exists but no ISO code");
401
	   		}else{
402

    
403
	   		}
404

    
405
	   		NamedArea subL4Area = null;
406
	   		Boolean subL4 = nullSafeBoolean(rs, "subL4");
407
	   		if (subL4 != null && subL4.booleanValue() == true){
408
	   			subL4Area = makeSubL4Area(state, gazetteerId);
409
	   			if (subL4Area != null){
410
	   				facade.addCollectingArea(subL4Area);
411
	   			}else{
412
	   				logger.warn("SubL4 area not found for gazetteerId: " + gazetteerId);
413
	   			}
414
	   		}
415

    
416
	   		if (country == null ){
417
	   			if (! gazetteerId.equals(40)){//special handling for Borneo, TDWG area is enough here as it matches exactly
418
		   			if (subL4Area == null ){
419
		   				logger.warn("Country does not exist and SubL4 could not be found for GazetteerID " + gazetteerId);
420
		   			}else {
421
		   				logger.info("Country could not be defined but subL4 area was added");
422
		   			}
423
	   			}
424
	   		}else{
425
	   			facade.setCountry(country);
426
	   		}
427

    
428
	   	}
429

    
430
	   	//Waterbody
431
	   	NamedArea waterbody = null;
432
	   	String waterbodyStr = rs.getString("WaterBody");
433
	   	if (isNotBlank(waterbodyStr)){
434
	   		if (waterbodyStr.equals("Atlantic Ocean")){
435
	   			waterbody = NamedArea.ATLANTICOCEAN();
436
	   		}else if (waterbodyStr.equals("Pacific Ocean")){
437
	   			waterbody = NamedArea.PACIFICOCEAN();
438
	   		}else if (waterbodyStr.equals("Indian Ocean")){
439
	   			waterbody = NamedArea.INDIANOCEAN();
440
	   		}else if (waterbodyStr.equals("Arctic Ocean")){
441
	   			waterbody = NamedArea.ARCTICOCEAN();
442
	   		}else{
443
	   			logger.warn("Waterbody not recognized: " + waterbody);
444
	   		}
445
	   		if (waterbody != null){
446
	   			facade.addCollectingArea(waterbody);
447
	   		}
448
	   	}
449

    
450

    
451
	   	//countries sub
452
	   	//TODO -> SpecimenImport (not existing in TypeSpecimen)
453
	}
454

    
455

    
456
	private NamedArea makeSubL4Area(AlgaTerraImportState state, Integer gazetteerId) {
457
		UUID uuid = subL4Mapping.get(gazetteerId);
458
		NamedArea area = (NamedArea)getTermService().find(uuid);
459
		if (area == null){
460
			logger.warn("SubL4 area could not be found in repository");
461
		}
462
		return area;
463
	}
464

    
465
	private boolean handleMissingCountry(AlgaTerraImportState state, DerivedUnitFacade facade, Integer gazetteerId) {
466
		NamedArea area = null;
467
		if (gazetteerId != null){
468
			if (gazetteerId.equals(42)){
469
				area = getNamedArea(state, AlgaTerraImportTransformer.uuidNamedAreaBorneo, null, null, null, null, null);
470
			}else if (gazetteerId.equals(1684)){
471
				area = getNamedArea(state, AlgaTerraImportTransformer.uuidNamedAreaPatagonia, null, null, null, null, null);
472
			}else if (gazetteerId.equals(2167)){
473
				area = getNamedArea(state, AlgaTerraImportTransformer.uuidNamedAreaTierraDelFuego, null, null, null, null, null);
474
			}
475
		}
476
		if (area != null){
477
			facade.addCollectingArea(area);
478
			return true;
479
		}
480
		return false;
481

    
482
	}
483

    
484
	protected SpecimenOrObservationType makeDerivedUnitType(String recordBasis) {
485
		SpecimenOrObservationType result = null;
486
		if (StringUtils.isBlank(recordBasis)){
487
			result = SpecimenOrObservationType.DerivedUnit;
488
		} else if (recordBasis.equalsIgnoreCase("FossileSpecimen")){
489
			result = SpecimenOrObservationType.Fossil;
490
		}else if (recordBasis.equalsIgnoreCase("HumanObservation")){
491
			result = SpecimenOrObservationType.HumanObservation;
492
		}else if (recordBasis.equalsIgnoreCase("Literature")){
493
			//FIXME
494
			logger.warn("Literature record basis not yet supported");
495
			result = SpecimenOrObservationType.DerivedUnit;
496
		}else if (recordBasis.equalsIgnoreCase("LivingSpecimen")){
497
			result = SpecimenOrObservationType.LivingSpecimen;
498
		}else if (recordBasis.equalsIgnoreCase("MachineObservation")){
499
			result = SpecimenOrObservationType.MachineObservation;
500
		}else if (recordBasis.equalsIgnoreCase("Observation")){
501
			result = SpecimenOrObservationType.Observation;
502
		}else if (recordBasis.equalsIgnoreCase("LivingCulture")){
503
			//FIXME
504
			logger.warn("LivingCulture record basis not yet supported");
505
			result = SpecimenOrObservationType.DerivedUnit;
506
		}else if (recordBasis.equalsIgnoreCase("PreservedSpecimen")){
507
			result = SpecimenOrObservationType.PreservedSpecimen;
508
		}
509
		return result;
510
	}
511

    
512

    
513
	protected Feature makeFeature(SpecimenOrObservationType type, AlgaTerraImportState state) {
514
		if (type.equals(SpecimenOrObservationType.DerivedUnit)){
515
			return Feature.INDIVIDUALS_ASSOCIATION();
516
		}else if (type.isFeatureObservation()){
517
			return Feature.OBSERVATION();
518
		}else if (type.isPreservedSpecimen()){
519
			return Feature.SPECIMEN();
520
		}else if (type.equals(SpecimenOrObservationType.LivingSpecimen)){
521
			UUID uuid = AlgaTerraImportTransformer.uuidFeatureLivingSpecimen;
522
			Feature feature = getFeature(state, uuid, "Living Specimen", "Living Specimen", null, Feature.SPECIMEN().getVocabulary());
523
			if (feature == null){
524
				logger.warn("Living Specimen Feature could not be created");
525
			}
526
			return feature;
527
		}
528
		logger.warn("No feature defined for derived unit type: " + type);
529
		return null;
530
	}
531

    
532
	private ReferenceSystem makeRefrenceSystem(String geoCodeMethod, AlgaTerraImportState state) {
533
		if (StringUtils.isBlank(geoCodeMethod)){
534
			return null;
535
		}else if(geoCodeMethod.startsWith("GPS")){
536
			getReferenceSystem(state, uuidRefSystemGps, "GPS", "GPS", "GPS", ReferenceSystem.GOOGLE_EARTH().getVocabulary());
537
			return ReferenceSystem.WGS84();
538
		}else if(geoCodeMethod.startsWith("Google")){
539
			return ReferenceSystem.GOOGLE_EARTH();
540
		}else if(geoCodeMethod.startsWith("Map")){
541
			return ReferenceSystem.MAP();
542
		}else if(geoCodeMethod.startsWith("WikiProjekt Georeferenzierung") || geoCodeMethod.startsWith("http://toolserver.org/~geohack/geohack.php") ){
543
			return ReferenceSystem.WGS84();
544
		}else {
545
			logger.warn("Reference system " +  geoCodeMethod +  " not yet supported.");
546
			return null;
547
		}
548
	}
549

    
550

    
551

    
552

    
553
	private void handleCollectorTeam(AlgaTerraImportState state, DerivedUnitFacade facade, ResultSet rs) throws SQLException {
554
		String collector = rs.getString("Collector");
555
		TeamOrPersonBase<?> author = getAuthor(collector);
556
		facade.setCollector(author);
557
	}
558

    
559
	/**
560
	 * @param facade
561
	 * @param collector
562
	 */
563
	protected TeamOrPersonBase<?> getAuthor(String author) {
564
		// FIXME TODO parsen und deduplizieren
565
		Team team = Team.NewTitledInstance(author, author);
566
		return team;
567
	}
568

    
569

    
570
	/**
571
	 * Use same TaxonDescription if two records belong to the same taxon
572
	 * @param state
573
	 * @param newTaxonId
574
	 * @param oldTaxonId
575
	 * @param oldDescription
576
	 * @param taxonMap
577
	 * @return
578
	 */
579
	protected TaxonDescription getTaxonDescription(AlgaTerraImportState state, Taxon taxon, Reference sourceSec){
580
		TaxonDescription result = null;
581
		Set<TaxonDescription> descriptionSet= taxon.getDescriptions();
582
		if (descriptionSet.size() > 0) {
583
			result = descriptionSet.iterator().next();
584
		}else{
585
			result = TaxonDescription.NewInstance();
586
			result.setTitleCache(sourceSec.getTitleCache(), true);
587
			taxon.addDescription(result);
588
		}
589
		return result;
590
	}
591

    
592

    
593

    
594

    
595
}
(12-12/15)