Project

General

Profile

Download (10.2 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2009 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
package eu.etaxonomy.cdm.io.dwca.in;
10

    
11
import java.util.ArrayList;
12
import java.util.HashSet;
13
import java.util.List;
14
import java.util.Map;
15
import java.util.Set;
16

    
17
import org.apache.log4j.Logger;
18

    
19
import eu.etaxonomy.cdm.api.facade.DerivedUnitFacade;
20
import eu.etaxonomy.cdm.io.dwca.TermUri;
21
import eu.etaxonomy.cdm.io.stream.StreamItem;
22
import eu.etaxonomy.cdm.model.agent.Institution;
23
import eu.etaxonomy.cdm.model.common.CdmBase;
24
import eu.etaxonomy.cdm.model.name.NameTypeDesignationStatus;
25
import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignationStatus;
26
import eu.etaxonomy.cdm.model.name.TaxonName;
27
import eu.etaxonomy.cdm.model.name.TypeDesignationStatusBase;
28
import eu.etaxonomy.cdm.model.occurrence.Collection;
29
import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
30
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationType;
31
import eu.etaxonomy.cdm.model.reference.Reference;
32
import eu.etaxonomy.cdm.model.taxon.Taxon;
33

    
34
/**
35
 * @author a.mueller
36
 * @date 22.11.2011
37
 *
38
 */
39
public class GbifTypesAndSpecimen2CdmConverter extends PartitionableConverterBase<DwcaDataImportConfiguratorBase, DwcaDataImportStateBase<DwcaDataImportConfiguratorBase>>
40
						implements IPartitionableConverter<StreamItem, IReader<CdmBase>, String>{
41

    
42
	@SuppressWarnings("unused")
43
	private static final Logger logger = Logger.getLogger(GbifTypesAndSpecimen2CdmConverter.class);
44

    
45
	private static final String CORE_ID = "coreId";
46

    
47
	/**
48
	 * @param state
49
	 */
50
	public GbifTypesAndSpecimen2CdmConverter(DwcaDataImportStateBase state) {
51
		super(state);
52
	}
53

    
54
	@Override
55
    public IReader<MappedCdmBase<? extends CdmBase>> map(StreamItem item ){
56
		List<MappedCdmBase<? extends CdmBase>> resultList = new ArrayList<>();
57

    
58
		Reference sourceReference = state.getTransactionalSourceReference();
59
		String sourceReferecenDetail = null;
60

    
61
		String id = getSourceId(item);
62
		Taxon taxon = getTaxonBase(id, item, Taxon.class, state);
63
		if (taxon != null){
64
			String typeStatusStr = item.get(TermUri.DWC_TYPE_STATUS);
65
			boolean isType = false;
66
			TypeDesignationStatusBase<?> typeStatus = null;
67
			if ( ! isNoTypeStatus(typeStatusStr)){
68
				isType = true;
69
				typeStatus = getTypeStatus(typeStatusStr, item);
70
			}
71

    
72
			SpecimenOrObservationType unitType = SpecimenOrObservationType.DerivedUnit;
73

    
74
			if (hasDerivedUnit(item, isType)){
75
				unitType = SpecimenOrObservationType.PreservedSpecimen;
76
			}else{
77
				unitType = SpecimenOrObservationType.FieldUnit;
78
			}
79

    
80
			DerivedUnitFacade facade = DerivedUnitFacade.NewInstance(unitType);
81

    
82
			String catalogNumber = item.get(TermUri.DWC_CATALOG_NUMBER);
83
			Collection collection = getCollection(state, item, resultList);
84
			facade.setCollection(collection);
85
			facade.setCatalogNumber(catalogNumber);
86

    
87
			DerivedUnit specimen = facade.innerDerivedUnit();
88

    
89
			if (isType){
90
				TaxonName name = taxon.getName();
91
				if (typeStatus.isInstanceOf(SpecimenTypeDesignationStatus.class)){
92
					SpecimenTypeDesignationStatus status = CdmBase.deproxy(typeStatus, SpecimenTypeDesignationStatus.class);
93
					name.addSpecimenTypeDesignation(specimen, status, null, null, null, false, true);
94
					MappedCdmBase<? extends CdmBase>  mcb = new MappedCdmBase<>(taxon);
95
					resultList.add(mcb);
96
				}else if (typeStatus.isInstanceOf(NameTypeDesignationStatus.class)){
97
					String message = "NameTypeDesignation not yet implemented";
98
					fireWarningEvent(message, item, 8);
99
				}else{
100
					String message = "Undefined type status: %s";
101
					message = String.format(message, typeStatus);
102
					fireWarningEvent(message, item, 8);
103
				}
104
			}
105

    
106
			MappedCdmBase<? extends CdmBase>  mcb = new MappedCdmBase<>(specimen);
107
			resultList.add(mcb);
108

    
109
		}else{
110
			String message = "Can't retrieve taxon from database for id '%s'";
111
			fireWarningEvent(String.format(message, id), item, 12);
112
		}
113

    
114
		//return
115
		return new ListReader<>(resultList);
116
	}
117

    
118

    
119
	private Collection getCollection(DwcaDataImportStateBase state, StreamItem item,
120
	        List<MappedCdmBase<? extends CdmBase>> resultList) {
121
		String institutionCode = item.get(TermUri.DWC_INSTITUTION_CODE);
122
		String collectionCode = item.get(TermUri.DWC_COLLECTION_CODE);
123
		//institution
124
		Institution institution = getInstitutionByInstitutionCode(item, institutionCode);
125
		if (institution != null){
126
			MappedCdmBase<? extends CdmBase>  mcb = new MappedCdmBase<>(item.term, item.get(TermUri.DWC_INSTITUTION_CODE), institution);
127
			resultList.add(mcb);
128
		}
129
		//collection
130
		Collection collection = getCollectionByCollectionCode(item, collectionCode, institution);
131
		if (collection != null){
132
			MappedCdmBase<? extends CdmBase>  mcb = new MappedCdmBase<>(item.term, item.get(TermUri.DWC_COLLECTION_CODE), collection);
133
			resultList.add(mcb);
134
		}
135
		return collection;
136
	}
137

    
138
	private Collection getCollectionByCollectionCode(StreamItem item, String collectionCode, Institution institution) {
139
		String namespace = TermUri.DWC_COLLECTION_CODE.toString();
140
		List<Collection> result = state.get(namespace, collectionCode, Collection.class);
141
		if (result.isEmpty()){
142
			return makeNewCollection(collectionCode, institution);
143
		}else if (result.size() == 1){
144
			return result.iterator().next();
145
		}else {
146
			int equalInstitutes = 0;
147
			Collection lastEqualInstituteCollection = null;
148
			String collectionInstitutionCode = makeCollectionInstitutionCode(collectionCode, institution);
149
			for (Collection collection: result){
150
				String collectionInstitutionCode2 = makeCollectionInstitutionCode(collection.getCode() ,institution);
151
				if (collectionInstitutionCode.equals(collectionInstitutionCode2)){
152
					equalInstitutes++;
153
					lastEqualInstituteCollection = collection;
154
				}
155
			}
156
			if(equalInstitutes == 0){
157
				return makeNewCollection(collectionCode, institution);
158
			}else{
159
				if (equalInstitutes > 1){
160
					String message = "There is more than 1 cdm entity matching given collection code '%s'. I take an arbitrary one.";
161
					fireWarningEvent(String.format(message, collectionCode), item, 4);
162
				}
163
				return lastEqualInstituteCollection;
164
			}
165
		}
166

    
167
	}
168

    
169
	/**
170
	 * @param collectionCode
171
	 * @param institution
172
	 */
173
	private String makeCollectionInstitutionCode(String collectionCode, Institution institution) {
174
		String collectionInstitutionCode = collectionCode + "@" + institution == null ? "NULL" : institution.getCode();
175
		return collectionInstitutionCode;
176
	}
177

    
178
	/**
179
	 * @param collectionCode
180
	 * @param institution
181
	 * @return
182
	 */
183
	private Collection makeNewCollection(String collectionCode,
184
			Institution institution) {
185
		//try to find in cdm
186
		Collection newCollection = Collection.NewInstance();
187
		newCollection.setCode(collectionCode);
188
		newCollection.setInstitute(institution);
189
		return newCollection;
190
	}
191

    
192
	private Institution getInstitutionByInstitutionCode(StreamItem item, String institutionCode) {
193
		String namespace = TermUri.DWC_COLLECTION_CODE.toString();
194
		List<Institution> result = state.get(namespace, institutionCode, Institution.class);
195
		if (result.isEmpty()){
196
			//try to find in cdm
197
			Institution newInstitution = Institution.NewInstance();
198
			newInstitution.setCode(institutionCode);
199
			return newInstitution;
200
		}
201
		if (result.size() > 1){
202
			String message = "There is more than 1 cdm entity matching given institution code '%s'. I take an arbitrary one.";
203
			fireWarningEvent(String.format(message, institutionCode), item, 4);
204
		}
205
		return result.iterator().next();
206
	}
207

    
208
	private boolean hasDerivedUnit(StreamItem item, boolean isType) {
209
		return isNotBlank(item.get(TermUri.DWC_INSTITUTION_CODE)) ||
210
				isNotBlank(item.get(TermUri.DWC_COLLECTION_CODE)) ||
211
				isNotBlank(item.get(TermUri.DWC_CATALOG_NUMBER))||
212
				isType;
213
		//TO BE CONTINUED
214
	}
215

    
216
	private boolean isNoTypeStatus(String typeStatus) {
217
		if (isBlank(typeStatus)){
218
			return true;
219
		}else if (typeStatus.equalsIgnoreCase("Nontype")){   //eMonocats Scratchpads
220
			return true;
221
		}else{
222
			return false;
223
		}
224
	}
225

    
226
	/**
227
	 * Returns the type designation. Should never return null
228
	 * except for blank typeStatus.
229
	 * @param typeStatus
230
	 * @param item
231
	 * @return
232
	 */
233
	private TypeDesignationStatusBase<?> getTypeStatus(String typeStatus, StreamItem item) {
234
		//TODO move to transformer or handle somehow different (e.g. transformer for http://vocabularies.gbif.org/vocabularies/type_status )
235
		//preliminary implementation for those types needed for eMonocots import
236
		if (isBlank(typeStatus)){
237
			return null;
238
		}else if (typeStatus.matches("(?i)holotype")){
239
			return SpecimenTypeDesignationStatus.HOLOTYPE();
240
		}else if (typeStatus.matches("(?i)syntype")){
241
			return SpecimenTypeDesignationStatus.SYNTYPE();
242
		}else{
243
			String message = "Type status not recognized: %s";
244
			message = String.format(message, typeStatus);
245
			fireWarningEvent(message, item, 12);
246
			return SpecimenTypeDesignationStatus.TYPE();
247
		}
248
	}
249

    
250
	@Override
251
	public String getSourceId(StreamItem item) {
252
		String id = item.get(CORE_ID);
253
		return id;
254
	}
255

    
256

    
257
//********************** PARTITIONABLE **************************************/
258

    
259
	@Override
260
	protected void makeForeignKeysForItem(StreamItem item, Map<String, Set<String>> fkMap) {
261
		String value;
262
		String key;
263
		//taxon
264
		if ( hasValue(value = item.get(CORE_ID))){
265
			key = TermUri.DWC_TAXON.toString();
266
			Set<String> keySet = getKeySet(key, fkMap);
267
			keySet.add(value);
268
		}
269

    
270
		//collection code
271
		TermUri uri = TermUri.DWC_COLLECTION_CODE;
272
		String valueStr = item.get(uri);
273
		if ( hasValue(value = valueStr)){
274
			key = uri.toString();
275
			Set<String> keySet = getKeySet(key, fkMap);
276
			keySet.add(value);
277
		}
278

    
279
	}
280

    
281

    
282
	@Override
283
	public Set<String> requiredSourceNamespaces() {
284
		Set<String> result = new HashSet<>();
285
 		result.add(TermUri.DWC_TAXON.toString());
286
 		result.add(TermUri.DWC_LOCATION_ID.toString());
287
 		return result;
288
	}
289

    
290
//******************* TO STRING ******************************************/
291

    
292
	@Override
293
	public String toString(){
294
		return this.getClass().getName();
295
	}
296

    
297

    
298
}
(20-20/37)