Project

General

Profile

Download (10.5 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.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;
18

    
19
import eu.etaxonomy.cdm.api.facade.DerivedUnitFacade;
20
import eu.etaxonomy.cdm.io.stream.IPartitionableConverter;
21
import eu.etaxonomy.cdm.io.stream.IReader;
22
import eu.etaxonomy.cdm.io.stream.ListReader;
23
import eu.etaxonomy.cdm.io.stream.MappedCdmBase;
24
import eu.etaxonomy.cdm.io.stream.PartitionableConverterBase;
25
import eu.etaxonomy.cdm.io.stream.StreamItem;
26
import eu.etaxonomy.cdm.io.stream.terms.TermUri;
27
import eu.etaxonomy.cdm.model.agent.Institution;
28
import eu.etaxonomy.cdm.model.common.CdmBase;
29
import eu.etaxonomy.cdm.model.name.NameTypeDesignationStatus;
30
import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignationStatus;
31
import eu.etaxonomy.cdm.model.name.TaxonName;
32
import eu.etaxonomy.cdm.model.name.TypeDesignationStatusBase;
33
import eu.etaxonomy.cdm.model.occurrence.Collection;
34
import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
35
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationType;
36
import eu.etaxonomy.cdm.model.reference.Reference;
37
import eu.etaxonomy.cdm.model.taxon.Taxon;
38

    
39
/**
40
 * @author a.mueller
41
 * @since 22.11.2011
42
 *
43
 */
44
public class GbifTypesAndSpecimen2CdmConverter extends PartitionableConverterBase<DwcaDataImportConfiguratorBase, DwcaDataImportStateBase<DwcaDataImportConfiguratorBase>>
45
						implements IPartitionableConverter<StreamItem, IReader<CdmBase>, String>{
46

    
47
	@SuppressWarnings("unused")
48
	private static final Logger logger = LogManager.getLogger(GbifTypesAndSpecimen2CdmConverter.class);
49

    
50
	private static final String CORE_ID = "coreId";
51

    
52
	/**
53
	 * @param state
54
	 */
55
	public GbifTypesAndSpecimen2CdmConverter(DwcaDataImportStateBase state) {
56
		super(state);
57
	}
58

    
59
	@Override
60
    public IReader<MappedCdmBase<? extends CdmBase>> map(StreamItem item ){
61
		List<MappedCdmBase<? extends CdmBase>> resultList = new ArrayList<>();
62

    
63
		Reference sourceReference = state.getTransactionalSourceReference();
64
		String sourceReferecenDetail = null;
65

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

    
77
			SpecimenOrObservationType unitType = SpecimenOrObservationType.DerivedUnit;
78

    
79
			if (hasDerivedUnit(item, isType)){
80
				unitType = SpecimenOrObservationType.PreservedSpecimen;
81
			}else{
82
				unitType = SpecimenOrObservationType.FieldUnit;
83
			}
84

    
85
			DerivedUnitFacade facade = DerivedUnitFacade.NewInstance(unitType);
86

    
87
			String catalogNumber = item.get(TermUri.DWC_CATALOG_NUMBER);
88
			Collection collection = getCollection(state, item, resultList);
89
			facade.setCollection(collection);
90
			facade.setCatalogNumber(catalogNumber);
91

    
92
			DerivedUnit specimen = facade.innerDerivedUnit();
93

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

    
111
			MappedCdmBase<? extends CdmBase>  mcb = new MappedCdmBase<>(specimen);
112
			resultList.add(mcb);
113

    
114
		}else{
115
			String message = "Can't retrieve taxon from database for id '%s'";
116
			fireWarningEvent(String.format(message, id), item, 12);
117
		}
118

    
119
		//return
120
		return new ListReader<>(resultList);
121
	}
122

    
123

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

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

    
172
	}
173

    
174
	/**
175
	 * @param collectionCode
176
	 * @param institution
177
	 */
178
	private String makeCollectionInstitutionCode(String collectionCode, Institution institution) {
179
		String collectionInstitutionCode = collectionCode + "@" + institution == null ? "NULL" : institution.getCode();
180
		return collectionInstitutionCode;
181
	}
182

    
183
	/**
184
	 * @param collectionCode
185
	 * @param institution
186
	 * @return
187
	 */
188
	private Collection makeNewCollection(String collectionCode,
189
			Institution institution) {
190
		//try to find in cdm
191
		Collection newCollection = Collection.NewInstance();
192
		newCollection.setCode(collectionCode);
193
		newCollection.setInstitute(institution);
194
		return newCollection;
195
	}
196

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

    
213
	private boolean hasDerivedUnit(StreamItem item, boolean isType) {
214
		return isNotBlank(item.get(TermUri.DWC_INSTITUTION_CODE)) ||
215
				isNotBlank(item.get(TermUri.DWC_COLLECTION_CODE)) ||
216
				isNotBlank(item.get(TermUri.DWC_CATALOG_NUMBER))||
217
				isType;
218
		//TO BE CONTINUED
219
	}
220

    
221
	private boolean isNoTypeStatus(String typeStatus) {
222
		if (isBlank(typeStatus)){
223
			return true;
224
		}else if (typeStatus.equalsIgnoreCase("Nontype")){   //eMonocats Scratchpads
225
			return true;
226
		}else{
227
			return false;
228
		}
229
	}
230

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

    
255
	@Override
256
	public String getSourceId(StreamItem item) {
257
		String id = item.get(CORE_ID);
258
		return id;
259
	}
260

    
261

    
262
//********************** PARTITIONABLE **************************************/
263

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

    
275
		//collection code
276
		TermUri uri = TermUri.DWC_COLLECTION_CODE;
277
		String valueStr = item.get(uri);
278
		if ( hasValue(value = valueStr)){
279
			key = uri.toString();
280
			Set<String> keySet = getKeySet(key, fkMap);
281
			keySet.add(value);
282
		}
283

    
284
	}
285

    
286

    
287
	@Override
288
	public Set<String> requiredSourceNamespaces() {
289
		Set<String> result = new HashSet<>();
290
 		result.add(TermUri.DWC_TAXON.toString());
291
 		result.add(TermUri.DWC_LOCATION_ID.toString());
292
 		return result;
293
	}
294

    
295
//******************* TO STRING ******************************************/
296

    
297
	@Override
298
	public String toString(){
299
		return this.getClass().getName();
300
	}
301

    
302

    
303
}
(16-16/17)