1
|
/**
|
2
|
* Copyright (C) 2016 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.specimen.gbif.in;
|
11
|
|
12
|
import java.io.IOException;
|
13
|
import java.net.URISyntaxException;
|
14
|
import java.util.Collection;
|
15
|
import java.util.HashMap;
|
16
|
import java.util.Iterator;
|
17
|
import java.util.List;
|
18
|
import java.util.Map;
|
19
|
import java.util.Set;
|
20
|
|
21
|
import org.apache.commons.lang.StringUtils;
|
22
|
import org.apache.http.client.ClientProtocolException;
|
23
|
import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;
|
24
|
import org.springframework.stereotype.Component;
|
25
|
|
26
|
import eu.etaxonomy.cdm.api.application.ICdmRepository;
|
27
|
import eu.etaxonomy.cdm.api.facade.DerivedUnitFacade;
|
28
|
import eu.etaxonomy.cdm.ext.occurrence.gbif.GbifQueryServiceWrapper;
|
29
|
import eu.etaxonomy.cdm.ext.occurrence.gbif.GbifResponse;
|
30
|
import eu.etaxonomy.cdm.io.specimen.SpecimenImportBase;
|
31
|
import eu.etaxonomy.cdm.io.specimen.SpecimenImportConfiguratorBase;
|
32
|
import eu.etaxonomy.cdm.io.specimen.SpecimenImportStateBase;
|
33
|
import eu.etaxonomy.cdm.model.agent.Institution;
|
34
|
import eu.etaxonomy.cdm.model.common.Language;
|
35
|
import eu.etaxonomy.cdm.model.name.TaxonName;
|
36
|
import eu.etaxonomy.cdm.model.occurrence.DerivationEvent;
|
37
|
import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
|
38
|
import eu.etaxonomy.cdm.model.occurrence.DeterminationEvent;
|
39
|
import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
|
40
|
import eu.etaxonomy.cdm.model.reference.Reference;
|
41
|
import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
|
42
|
import eu.etaxonomy.cdm.model.taxon.Classification;
|
43
|
import eu.etaxonomy.cdm.model.taxon.Taxon;
|
44
|
import eu.etaxonomy.cdm.persistence.query.MatchMode;
|
45
|
|
46
|
/**
|
47
|
* @author k.luther
|
48
|
* @since 15.07.2016
|
49
|
*
|
50
|
*/
|
51
|
@Component
|
52
|
public class GbifImport extends SpecimenImportBase<GbifImportConfigurator, SpecimenImportStateBase<SpecimenImportConfiguratorBase, SpecimenImportStateBase>> {
|
53
|
/**
|
54
|
*
|
55
|
*/
|
56
|
private static final long serialVersionUID = 1L;
|
57
|
private static final Logger logger = LogManager.getLogger(GbifImport.class);
|
58
|
|
59
|
@Override
|
60
|
protected boolean doCheck(SpecimenImportStateBase<SpecimenImportConfiguratorBase, SpecimenImportStateBase> state) {
|
61
|
logger.warn("Checking not yet implemented for " + this.getClass().getSimpleName());
|
62
|
return true;
|
63
|
}
|
64
|
|
65
|
|
66
|
|
67
|
|
68
|
|
69
|
|
70
|
/* (non-Javadoc)
|
71
|
* @see eu.etaxonomy.cdm.io.specimen.SpecimenImportBase#doInvoke(eu.etaxonomy.cdm.io.common.ImportStateBase)
|
72
|
*/
|
73
|
@Override
|
74
|
protected void doInvoke(SpecimenImportStateBase state) {
|
75
|
// GbifImportState gbifImportState = (GbifImportState)state;
|
76
|
SpecimenImportConfiguratorBase config = state.getConfig();
|
77
|
|
78
|
state.setTx(startTransaction());
|
79
|
logger.info("INVOKE Specimen Import from Gbif webservice");
|
80
|
Collection<GbifResponse> results = null;
|
81
|
//init cd repository
|
82
|
if(state.getCdmRepository()==null){
|
83
|
state.setCdmRepository(this);
|
84
|
}
|
85
|
if (config.getOccurenceQuery() != null){
|
86
|
try {
|
87
|
results = new GbifQueryServiceWrapper().query(config.getOccurenceQuery());
|
88
|
} catch (ClientProtocolException e) {
|
89
|
// TODO Auto-generated catch block
|
90
|
e.printStackTrace();
|
91
|
} catch (IOException e) {
|
92
|
// TODO Auto-generated catch block
|
93
|
e.printStackTrace();
|
94
|
} catch (URISyntaxException e) {
|
95
|
// TODO Auto-generated catch block
|
96
|
e.printStackTrace();
|
97
|
}
|
98
|
|
99
|
|
100
|
}
|
101
|
if (results == null){
|
102
|
logger.info("There were no results for the query: " + config.getOccurenceQuery().toString());
|
103
|
return;
|
104
|
}
|
105
|
List<Reference> references = getReferenceService().listByReferenceTitleWithRestrictions(Reference.class, state.getConfig().getSourceReferenceTitle(), MatchMode.LIKE, null, null, null, null, null);
|
106
|
//List<Reference> references = new ArrayList<Reference>();
|
107
|
if (state.getRef()==null){
|
108
|
String name = NB(( state.getConfig()).getSourceReferenceTitle());
|
109
|
for (Reference reference : references) {
|
110
|
if (! StringUtils.isBlank(reference.getTitleCache())) {
|
111
|
if (reference.getTitleCache().equalsIgnoreCase(name)) {
|
112
|
state.setRef(reference);
|
113
|
}
|
114
|
}
|
115
|
}
|
116
|
if (state.getRef() == null){
|
117
|
state.setRef(ReferenceFactory.newGeneric());
|
118
|
state.getRef().setTitle(state.getConfig().getSourceReferenceTitle() + " Test ");
|
119
|
}
|
120
|
}
|
121
|
//}
|
122
|
save(state.getRef(), state);
|
123
|
state.getConfig().setSourceReference(state.getRef());
|
124
|
if(state.getConfig().getClassificationUuid()!=null){
|
125
|
//load classification from config if it exists
|
126
|
state.setClassification(getClassificationService().load(state.getConfig().getClassificationUuid()));
|
127
|
}
|
128
|
if(state.getClassification()==null){//no existing classification was set in config
|
129
|
List<Classification> classificationList = getClassificationService().list(Classification.class, null, null, null, null);
|
130
|
//get classification via user interaction
|
131
|
if (state.getConfig().isUseClassification() && state.getConfig().isInteractWithUser()){
|
132
|
Map<String,Classification> classMap = new HashMap<String, Classification>();
|
133
|
for (Classification tree : classificationList) {
|
134
|
if (! StringUtils.isBlank(tree.getTitleCache())) {
|
135
|
classMap.put(tree.getTitleCache(),tree);
|
136
|
}
|
137
|
}
|
138
|
|
139
|
}
|
140
|
// use default classification as the classification to import into
|
141
|
if (state.getClassification() == null) {
|
142
|
String name = NB(state.getConfig().getClassificationName());
|
143
|
for (Classification classif : classificationList){
|
144
|
if (classif.getTitleCache() != null && classif.getTitleCache().equalsIgnoreCase(name)) {
|
145
|
state.setClassification(classif);
|
146
|
}
|
147
|
}
|
148
|
if (state.getClassification() == null){
|
149
|
state.setClassification(Classification.NewInstance(name, state.getRef(), Language.DEFAULT()));
|
150
|
//we do not need a default classification when creating an empty new one
|
151
|
state.setDefaultClassification(state.getClassification());
|
152
|
|
153
|
}
|
154
|
|
155
|
}
|
156
|
}
|
157
|
String message = "nb units to insert: " + results.size();
|
158
|
logger.info(message);
|
159
|
state.getConfig().getProgressMonitor().beginTask("Importing ABCD file", results.size());
|
160
|
updateProgress(state, message);
|
161
|
|
162
|
state.setDataHolder(new GbifDataHolder());
|
163
|
state.getDataHolder().reset();
|
164
|
|
165
|
for (GbifResponse response:results) {
|
166
|
if(state.getConfig().getProgressMonitor().isCanceled()){
|
167
|
logger.info("Import has been canceled");
|
168
|
break;
|
169
|
}
|
170
|
|
171
|
|
172
|
|
173
|
|
174
|
//this.setUnitPropertiesXML( item, abcdFieldGetter, state);
|
175
|
// updateProgress(state, "Importing data for unit "+state.getDataHolder().unitID+" ("+i+"/"+unitsList.getLength()+")");
|
176
|
|
177
|
//import unit + field unit data
|
178
|
this.handleSingleUnit(state, response);
|
179
|
|
180
|
}
|
181
|
|
182
|
|
183
|
commitTransaction(state.getTx());
|
184
|
|
185
|
|
186
|
|
187
|
}
|
188
|
|
189
|
@Override
|
190
|
protected void importAssociatedUnits(
|
191
|
SpecimenImportStateBase<SpecimenImportConfiguratorBase, SpecimenImportStateBase> state, Object item,
|
192
|
DerivedUnitFacade derivedUnitFacade) {
|
193
|
|
194
|
//import associated units
|
195
|
FieldUnit currentFieldUnit = derivedUnitFacade.innerFieldUnit();
|
196
|
//TODO: push state (think of implementing stack architecture for state
|
197
|
DerivedUnit currentUnit = state.getDerivedUnitBase();
|
198
|
if (currentUnit != null){
|
199
|
DerivationEvent currentDerivedFrom = currentUnit.getDerivedFrom();
|
200
|
}
|
201
|
/* NodeList unitAssociationList = item.getElementsByTagName(currentPrefix+"UnitAssociation");
|
202
|
for(int k=0;k<unitAssociationList.getLength();k++){
|
203
|
if(unitAssociationList.item(k) instanceof Element){
|
204
|
Element unitAssociation = (Element)unitAssociationList.item(k);
|
205
|
UnitAssociationParser unitAssociationParser = new UnitAssociationParser(currentPrefix, state.getReport(), state.getCdmRepository());
|
206
|
UnitAssociationWrapper associationWrapper = unitAssociationParser.parse(unitAssociation);
|
207
|
if(associationWrapper!=null){
|
208
|
NodeList associatedUnits = associationWrapper.getAssociatedUnits();
|
209
|
if(associatedUnits!=null){
|
210
|
for(int m=0;m<associatedUnits.getLength();m++){
|
211
|
if(associatedUnits.item(m) instanceof Element){
|
212
|
state.reset();
|
213
|
state.setPrefix(associationWrapper.getPrefix());
|
214
|
this.setUnitPropertiesXML((Element) associatedUnits.item(m), new Abcd206XMLFieldGetter(state.getDataHolder(), state.getPrefix()), state);
|
215
|
handleSingleUnit(state, associatedUnits.item(m));
|
216
|
|
217
|
DerivedUnit associatedUnit = state.getDerivedUnitBase();
|
218
|
FieldUnit associatedFieldUnit = null;
|
219
|
java.util.Collection<FieldUnit> associatedFieldUnits = state.getCdmRepository().getOccurrenceService().getFieldUnits(associatedUnit.getUuid());
|
220
|
//ignore field unit if associated unit has more than one
|
221
|
if(associatedFieldUnits.size()>1){
|
222
|
state.getReport().addInfoMessage(String.format("%s has more than one field unit.", associatedUnit));
|
223
|
}
|
224
|
else if(associatedFieldUnits.size()==1){
|
225
|
associatedFieldUnit = associatedFieldUnits.iterator().next();
|
226
|
}
|
227
|
|
228
|
//attach current unit and associated unit depending on association type
|
229
|
|
230
|
//parent-child relation:
|
231
|
//copy derivation event and connect parent and sub derivative
|
232
|
if(associationWrapper.getAssociationType().contains("individual")){
|
233
|
if(currentDerivedFrom==null){
|
234
|
state.getReport().addInfoMessage(String.format("No derivation event found for unit %s. Defaulting to ACCESSIONING event.",AbcdImportUtility.getUnitID(currentUnit, config)));
|
235
|
DerivationEvent.NewSimpleInstance(associatedUnit, currentUnit, DerivationEventType.ACCESSIONING());
|
236
|
}
|
237
|
else{
|
238
|
DerivationEvent updatedDerivationEvent = DerivationEvent.NewSimpleInstance(associatedUnit, currentUnit, currentDerivedFrom.getType());
|
239
|
updatedDerivationEvent.setActor(currentDerivedFrom.getActor());
|
240
|
updatedDerivationEvent.setDescription(currentDerivedFrom.getDescription());
|
241
|
updatedDerivationEvent.setInstitution(currentDerivedFrom.getInstitution());
|
242
|
updatedDerivationEvent.setTimeperiod(currentDerivedFrom.getTimeperiod());
|
243
|
}
|
244
|
state.getReport().addDerivate(associatedUnit, currentUnit, config);
|
245
|
}
|
246
|
//siblings relation
|
247
|
//connect current unit to field unit of associated unit
|
248
|
else if(associationWrapper.getAssociationType().contains("population")){
|
249
|
//no associated field unit -> using current one
|
250
|
if(associatedFieldUnit==null){
|
251
|
if(currentFieldUnit!=null){
|
252
|
DerivationEvent.NewSimpleInstance(currentFieldUnit, associatedUnit, DerivationEventType.ACCESSIONING());
|
253
|
}
|
254
|
}
|
255
|
else{
|
256
|
if(currentDerivedFrom==null){
|
257
|
state.getReport().addInfoMessage("No derivation event found for unit "+AbcdImportUtility.getUnitID(currentUnit, config)+". Defaulting to ACCESIONING event.");
|
258
|
DerivationEvent.NewSimpleInstance(associatedFieldUnit, currentUnit, DerivationEventType.ACCESSIONING());
|
259
|
}
|
260
|
if(currentDerivedFrom!=null && associatedFieldUnit!=currentFieldUnit){
|
261
|
DerivationEvent updatedDerivationEvent = DerivationEvent.NewSimpleInstance(associatedFieldUnit, currentUnit, currentDerivedFrom.getType());
|
262
|
updatedDerivationEvent.setActor(currentDerivedFrom.getActor());
|
263
|
updatedDerivationEvent.setDescription(currentDerivedFrom.getDescription());
|
264
|
updatedDerivationEvent.setInstitution(currentDerivedFrom.getInstitution());
|
265
|
updatedDerivationEvent.setTimeperiod(currentDerivedFrom.getTimeperiod());
|
266
|
}
|
267
|
}
|
268
|
}
|
269
|
|
270
|
//delete current field unit if replaced
|
271
|
if(currentFieldUnit!=null && currentDerivedFrom!=null
|
272
|
&& currentFieldUnit.getDerivationEvents().size()==1 && currentFieldUnit.getDerivationEvents().contains(currentDerivedFrom) //making sure that the field unit
|
273
|
&& currentDerivedFrom.getDerivatives().size()==1 && currentDerivedFrom.getDerivatives().contains(currentUnit) //is not attached to other derived units
|
274
|
&& currentDerivedFrom!=currentUnit.getDerivedFrom() // <- derivation has been replaced and can be deleted
|
275
|
){
|
276
|
currentFieldUnit.removeDerivationEvent(currentDerivedFrom);
|
277
|
state.getCdmRepository().getOccurrenceService().delete(currentFieldUnit);
|
278
|
}
|
279
|
|
280
|
save(associatedUnit, state);
|
281
|
}
|
282
|
}
|
283
|
}
|
284
|
}
|
285
|
}
|
286
|
}*/
|
287
|
//TODO: pop state
|
288
|
state.reset();
|
289
|
state.setDerivedUnitBase(currentUnit);
|
290
|
|
291
|
}
|
292
|
|
293
|
|
294
|
@Override
|
295
|
protected void handleSingleUnit(SpecimenImportStateBase<SpecimenImportConfiguratorBase, SpecimenImportStateBase> state,
|
296
|
Object itemObject){
|
297
|
GbifResponse item;
|
298
|
if (itemObject instanceof GbifResponse){
|
299
|
item = (GbifResponse) itemObject;
|
300
|
} else{
|
301
|
logger.error("For Gbif Import the item has to be of type GbifResponse.");
|
302
|
return;
|
303
|
}
|
304
|
if (logger.isDebugEnabled()) {
|
305
|
logger.info("handleSingleUnit "+state.getRef());
|
306
|
}
|
307
|
|
308
|
ICdmRepository cdmAppController = state.getConfig().getCdmAppController();
|
309
|
if(cdmAppController==null){
|
310
|
cdmAppController = this;
|
311
|
}
|
312
|
//check if unit already exists
|
313
|
DerivedUnitFacade derivedUnitFacade;
|
314
|
derivedUnitFacade = item.getDerivedUnitFacade();
|
315
|
state.setDerivedUnitBase(derivedUnitFacade.innerDerivedUnit());
|
316
|
TaxonName bestMatchingName = findBestMatchingNames(item, state);
|
317
|
if (bestMatchingName == null){
|
318
|
bestMatchingName = item.getScientificName();
|
319
|
}
|
320
|
if (bestMatchingName != null){
|
321
|
Taxon taxon = getOrCreateTaxonForName(bestMatchingName, state);
|
322
|
if (state.getConfig().isAddIndividualsAssociationsSuchAsSpecimenAndObservations()) {
|
323
|
//do not add IndividualsAssociation to non-preferred taxa
|
324
|
if(logger.isDebugEnabled()){
|
325
|
logger.info("isDoCreateIndividualsAssociations");
|
326
|
}
|
327
|
for (DeterminationEvent determinationEvent:derivedUnitFacade.getDeterminations()){
|
328
|
makeIndividualsAssociation(state, taxon, determinationEvent);
|
329
|
}
|
330
|
|
331
|
save(state.getDerivedUnitBase(), state);
|
332
|
}
|
333
|
}
|
334
|
|
335
|
|
336
|
|
337
|
// handle collection data
|
338
|
handleCollectionData(state, derivedUnitFacade);
|
339
|
// save(item.getDerivedUnitFacade().baseUnit(), state);
|
340
|
// save(item.getDerivedUnitFacade().getFieldUnit(false), state);
|
341
|
importAssociatedUnits(state, item, derivedUnitFacade);
|
342
|
/*
|
343
|
if(state.getConfig().isIgnoreImportOfExistingSpecimens()){
|
344
|
String[] tripleId = item.getTripleID();
|
345
|
SpecimenOrObservationBase<?> existingSpecimen = findExistingSpecimen(tripleId[0], state);
|
346
|
DerivedUnitFacade derivedUnitFacade;
|
347
|
if(existingSpecimen!=null && existingSpecimen.isInstanceOf(DerivedUnit.class)){
|
348
|
DerivedUnit derivedUnit = HibernateProxyHelper.deproxy(existingSpecimen, DerivedUnit.class);
|
349
|
state.setDerivedUnitBase(derivedUnit);
|
350
|
derivedUnitFacade = item.getDerivedUnitFacade();
|
351
|
List<NonViralName> names = findExistingNames(item.getScientificName().getNameCache(), state);
|
352
|
if (!names.isEmpty()){
|
353
|
findBestMatchingName(names, item);
|
354
|
}
|
355
|
save(item.getDerivedUnitFacade().baseUnit(), state);
|
356
|
importAssociatedUnits(state, item, derivedUnitFacade);
|
357
|
state.getReport().addAlreadyExistingSpecimen(SpecimenImportUtility.getUnitID(derivedUnit, state.getConfig()), derivedUnit);
|
358
|
return;
|
359
|
}
|
360
|
}
|
361
|
|
362
|
//import new specimen
|
363
|
|
364
|
// import DNA unit
|
365
|
//TODO!!!!
|
366
|
if(state.getDataHolder().getKindOfUnit()!=null && state.getDataHolder().getKindOfUnit().equalsIgnoreCase("dna")){
|
367
|
GbifDnaParser dnaParser = new GbifDnaParser(state.getPrefix(), state.getReport(), state.getCdmRepository());
|
368
|
DnaSample dnaSample = dnaParser.parse(item, state);
|
369
|
save(dnaSample, state);
|
370
|
//set dna as derived unit to avoid creating an extra specimen for this dna sample (instead just the field unit will be created)
|
371
|
state.setDerivedUnitBase(dnaSample);
|
372
|
derivedUnitFacade = DerivedUnitFacade.NewInstance(state.getDerivedUnitBase());
|
373
|
}
|
374
|
else{
|
375
|
// create facade
|
376
|
derivedUnitFacade = getFacade(state);
|
377
|
state.setDerivedUnitBase(derivedUnitFacade.innerDerivedUnit());
|
378
|
// }
|
379
|
|
380
|
/**
|
381
|
* GATHERING EVENT
|
382
|
|
383
|
// gathering event
|
384
|
UnitsGatheringEvent<GbifImportConfigurator> unitsGatheringEvent =
|
385
|
/* new UnitsGatheringEvent<GbifImportConfigurator>(cdmAppController.getTermService(),
|
386
|
state.getDataHolder().locality, null, state.getDataHolder().decimalLongitude,
|
387
|
state.getDataHolder().decimalLatitude, state.getDataHolder().getGatheringElevationText(),
|
388
|
state.getDataHolder().getGatheringElevationMin(), state.getDataHolder().getGatheringElevationMax(),
|
389
|
state.getDataHolder().getGatheringElevationUnit(), state.getDataHolder().getGatheringDateText(),
|
390
|
state.getDataHolder().getGatheringNotes(), state.getTransformer().getReferenceSystemByKey(
|
391
|
state.getDataHolder().getGatheringSpatialDatum()), state.getDataHolder().gatheringAgentList,
|
392
|
state.getDataHolder().gatheringTeamList, state.getConfig());
|
393
|
|
394
|
// country
|
395
|
UnitsGatheringArea unitsGatheringArea = new UnitsGatheringArea();
|
396
|
// unitsGatheringArea.setConfig(state.getConfig(),getOccurrenceService(), getTermService());
|
397
|
unitsGatheringArea.setParams(state.getDataHolder().countryCode, state.getDataHolder().country, state.getConfig(), cdmAppController.getTermService(), cdmAppController.getOccurrenceService());
|
398
|
|
399
|
DefinedTermBase<?> areaCountry = unitsGatheringArea.getCountry();
|
400
|
|
401
|
// other areas
|
402
|
unitsGatheringArea = new UnitsGatheringArea();
|
403
|
// unitsGatheringArea.setConfig(state.getConfig(),getOccurrenceService(),getTermService());
|
404
|
unitsGatheringArea.setAreas(state.getDataHolder().getNamedAreaList(),state.getConfig(), cdmAppController.getTermService(), cdmAppController.getVocabularyService());
|
405
|
ArrayList<DefinedTermBase> nas = unitsGatheringArea.getAreas();
|
406
|
for (DefinedTermBase namedArea : nas) {
|
407
|
unitsGatheringEvent.addArea(namedArea);
|
408
|
}
|
409
|
|
410
|
// copy gathering event to facade
|
411
|
GatheringEvent gatheringEvent = unitsGatheringEvent.getGatheringEvent();
|
412
|
derivedUnitFacade.setLocality(gatheringEvent.getLocality());
|
413
|
derivedUnitFacade.setExactLocation(gatheringEvent.getExactLocation());
|
414
|
derivedUnitFacade.setCollector(gatheringEvent.getCollector());
|
415
|
derivedUnitFacade.setCountry((NamedArea)areaCountry);
|
416
|
derivedUnitFacade.setAbsoluteElevationText(gatheringEvent.getAbsoluteElevationText());
|
417
|
derivedUnitFacade.setAbsoluteElevation(gatheringEvent.getAbsoluteElevation());
|
418
|
derivedUnitFacade.setAbsoluteElevationMax(gatheringEvent.getAbsoluteElevationMax());
|
419
|
derivedUnitFacade.setGatheringPeriod(gatheringEvent.getTimeperiod());
|
420
|
|
421
|
for(DefinedTermBase<?> area:unitsGatheringArea.getAreas()){
|
422
|
derivedUnitFacade.addCollectingArea((NamedArea) area);
|
423
|
}
|
424
|
// derivedUnitFacade.addCollectingAreas(unitsGatheringArea.getAreas());
|
425
|
// TODO exsiccatum
|
426
|
|
427
|
// add fieldNumber
|
428
|
derivedUnitFacade.setFieldNumber(NB(state.getDataHolder().getFieldNumber()));
|
429
|
|
430
|
// add unitNotes
|
431
|
derivedUnitFacade.addAnnotation(Annotation.NewDefaultLanguageInstance(NB(state.getDataHolder().getUnitNotes())));
|
432
|
|
433
|
// //add Multimedia URLs
|
434
|
if (state.getDataHolder().getMultimediaObjects().size() != -1) {
|
435
|
for (String multimediaObject : state.getDataHolder().getMultimediaObjects()) {
|
436
|
Media media;
|
437
|
try {
|
438
|
media = getImageMedia(multimediaObject, READ_MEDIA_DATA);
|
439
|
derivedUnitFacade.addDerivedUnitMedia(media);
|
440
|
if(state.getConfig().isAddMediaAsMediaSpecimen()){
|
441
|
//add media also as specimen scan
|
442
|
MediaSpecimen mediaSpecimen = MediaSpecimen.NewInstance(SpecimenOrObservationType.Media);
|
443
|
mediaSpecimen.setMediaSpecimen(media);
|
444
|
DefinedTermBase specimenScanTerm = getTermService().load(SPECIMEN_SCAN_TERM);
|
445
|
if(specimenScanTerm instanceof DefinedTerm){
|
446
|
mediaSpecimen.setKindOfUnit((DefinedTerm) specimenScanTerm);
|
447
|
}
|
448
|
DerivationEvent derivationEvent = DerivationEvent.NewInstance(DerivationEventType.PREPARATION());
|
449
|
derivationEvent.addDerivative(mediaSpecimen);
|
450
|
derivedUnitFacade.innerDerivedUnit().addDerivationEvent(derivationEvent);
|
451
|
}
|
452
|
|
453
|
} catch (MalformedURLException e) {
|
454
|
// TODO Auto-generated catch block
|
455
|
e.printStackTrace();
|
456
|
}
|
457
|
|
458
|
}
|
459
|
}
|
460
|
|
461
|
// /*
|
462
|
// * merge AND STORE DATA
|
463
|
//
|
464
|
// getTermService().saveOrUpdate(areaCountry);// TODO save area sooner
|
465
|
//
|
466
|
// for (NamedArea area : otherAreas) {
|
467
|
// getTermService().saveOrUpdate(area);// merge it sooner (foreach area)
|
468
|
// }
|
469
|
|
470
|
save(unitsGatheringEvent.getLocality(), state);
|
471
|
|
472
|
// handle collection data
|
473
|
setCollectionData(state, derivedUnitFacade);
|
474
|
|
475
|
//Reference stuff
|
476
|
// SpecimenUserInteraction sui = state.getConfig().getSpecimenUserInteraction();
|
477
|
Map<String,OriginalSourceBase> sourceMap = new HashMap<String, OriginalSourceBase>();
|
478
|
|
479
|
state.getDataHolder().docSources = new ArrayList<String>();
|
480
|
for (String[] fullReference : state.getDataHolder().referenceList) {
|
481
|
String strReference=fullReference[0];
|
482
|
String citationDetail = fullReference[1];
|
483
|
String citationURL = fullReference[2];
|
484
|
|
485
|
if (!citationURL.isEmpty()) {
|
486
|
citationDetail+=", "+citationURL;
|
487
|
}
|
488
|
|
489
|
Reference reference;
|
490
|
if(strReference.equals(state.getRef().getTitleCache())){
|
491
|
reference = state.getRef();
|
492
|
}
|
493
|
else{
|
494
|
reference = ReferenceFactory.newGeneric();
|
495
|
reference.setTitle(strReference);
|
496
|
}
|
497
|
|
498
|
IdentifiableSource sour = getIdentifiableSource(reference,citationDetail);
|
499
|
|
500
|
try{
|
501
|
if (sour.getCitation() != null){
|
502
|
if(StringUtils.isNotBlank(sour.getCitationMicroReference())) {
|
503
|
state.getDataHolder().docSources.add(sour.getCitation().getTitleCache()+ "---"+sour.getCitationMicroReference());
|
504
|
} else {
|
505
|
state.getDataHolder().docSources.add(sour.getCitation().getTitleCache());
|
506
|
}
|
507
|
}
|
508
|
}catch(Exception e){
|
509
|
logger.warn("oups");
|
510
|
}
|
511
|
reference.addSource(sour);
|
512
|
save(reference, state);
|
513
|
}
|
514
|
List<IdentifiableSource> issTmp = new ArrayList<IdentifiableSource>();//getCommonService().list(IdentifiableSource.class, null, null, null, null);
|
515
|
List<DescriptionElementSource> issTmp2 = new ArrayList<DescriptionElementSource>();//getCommonService().list(DescriptionElementSource.class, null, null, null, null);
|
516
|
|
517
|
Set<OriginalSourceBase> osbSet = new HashSet<OriginalSourceBase>();
|
518
|
if(issTmp2!=null) {
|
519
|
osbSet.addAll(issTmp2);
|
520
|
}
|
521
|
if(issTmp!=null) {
|
522
|
osbSet.addAll(issTmp);
|
523
|
}
|
524
|
|
525
|
addToSourceMap(sourceMap, osbSet);
|
526
|
|
527
|
if( state.getConfig().isInteractWithUser()){
|
528
|
List<OriginalSourceBase>sources=null;
|
529
|
if(!state.isDerivedUnitSourcesSet()){
|
530
|
sources= sui.askForSource(sourceMap, "the unit itself","",getReferenceService(), state.getDataHolder().docSources);
|
531
|
state.setDerivedUnitSources(sources);
|
532
|
state.setDerivedUnitSourcesSet(true);
|
533
|
}
|
534
|
else{
|
535
|
sources=state.getDerivedUnitSources();
|
536
|
}
|
537
|
// System.out.println("nb sources: "+sources.size());
|
538
|
// System.out.println("derivedunitfacade : "+derivedUnitFacade.getTitleCache());
|
539
|
for (OriginalSourceBase sour:sources){
|
540
|
if(sour.isInstanceOf(IdentifiableSource.class)){
|
541
|
if(sourceNotLinkedToElement(derivedUnitFacade,sour)) {
|
542
|
// System.out.println("add source to derivedunitfacade1 "+derivedUnitFacade.getTitleCache());
|
543
|
derivedUnitFacade.addSource((IdentifiableSource)sour.clone());
|
544
|
}
|
545
|
}else{
|
546
|
if(sourceNotLinkedToElement(derivedUnitFacade,sour)) {
|
547
|
// System.out.println("add source to derivedunitfacade2 "+derivedUnitFacade.getTitleCache());
|
548
|
derivedUnitFacade.addSource(OriginalSourceType.Import,sour.getCitation(),sour.getCitationMicroReference(), ioName);
|
549
|
}
|
550
|
}
|
551
|
}
|
552
|
}else{
|
553
|
for (OriginalSourceBase sr : sourceMap.values()){
|
554
|
if(sr.isInstanceOf(IdentifiableSource.class)){
|
555
|
if(sourceNotLinkedToElement(derivedUnitFacade,sr)) {
|
556
|
// System.out.println("add source to derivedunitfacade3 "+derivedUnitFacade.getTitleCache());
|
557
|
derivedUnitFacade.addSource((IdentifiableSource)sr.clone());
|
558
|
}
|
559
|
}else{
|
560
|
if(sourceNotLinkedToElement(derivedUnitFacade,sr)) {
|
561
|
// System.out.println("add source to derivedunitfacade4 "+derivedUnitFacade.getTitleCache());
|
562
|
derivedUnitFacade.addSource(OriginalSourceType.Import,sr.getCitation(),sr.getCitationMicroReference(), ioName);
|
563
|
}
|
564
|
}
|
565
|
}
|
566
|
}
|
567
|
|
568
|
save(item, state);
|
569
|
|
570
|
if(DEBUG) {
|
571
|
logger.info("saved ABCD specimen ...");
|
572
|
}
|
573
|
|
574
|
// handle identifications
|
575
|
handleIdentifications(state, derivedUnitFacade);
|
576
|
|
577
|
//associatedUnits
|
578
|
importAssociatedUnits(state, item, derivedUnitFacade);
|
579
|
|
580
|
|
581
|
|
582
|
} catch (Exception e) {
|
583
|
String message = "Error when reading record!";
|
584
|
logger.warn(message);
|
585
|
state.getReport().addException(message, e);
|
586
|
e.printStackTrace();
|
587
|
state.setUnsuccessfull();
|
588
|
}
|
589
|
*/
|
590
|
return;
|
591
|
}
|
592
|
|
593
|
|
594
|
/**
|
595
|
* @param state
|
596
|
* @param derivedUnitFacade
|
597
|
*/
|
598
|
private void handleCollectionData(
|
599
|
SpecimenImportStateBase<SpecimenImportConfiguratorBase, SpecimenImportStateBase> state,
|
600
|
DerivedUnitFacade derivedUnitFacade) {
|
601
|
eu.etaxonomy.cdm.model.occurrence.Collection collection = derivedUnitFacade.getCollection();
|
602
|
if (collection != null) {
|
603
|
Institution institution = getInstitution(collection.getInstitute().getCode(), state);
|
604
|
|
605
|
collection = getCollection(institution, collection.getCode(), state);
|
606
|
}
|
607
|
|
608
|
}
|
609
|
|
610
|
|
611
|
/**
|
612
|
* @param state
|
613
|
* @param derivedUnitFacade
|
614
|
*/
|
615
|
private void handleDeterminations(
|
616
|
SpecimenImportStateBase<SpecimenImportConfiguratorBase, SpecimenImportStateBase> state,
|
617
|
DerivedUnitFacade derivedUnitFacade) {
|
618
|
SpecimenImportConfiguratorBase config = state.getConfig();
|
619
|
|
620
|
|
621
|
String scientificName = "";
|
622
|
boolean preferredFlag = false;
|
623
|
|
624
|
if (state.getDataHolder().getNomenclatureCode() == ""){
|
625
|
state.getDataHolder().setNomenclatureCode(config.getNomenclaturalCode().toString());
|
626
|
}
|
627
|
Set<DeterminationEvent> determinations = derivedUnitFacade.getDeterminations();
|
628
|
Iterator<DeterminationEvent> determinationIterator = determinations.iterator();
|
629
|
DeterminationEvent event;
|
630
|
Taxon taxon;
|
631
|
TaxonName name ;
|
632
|
while (determinationIterator.hasNext()) {
|
633
|
event = determinationIterator.next();
|
634
|
taxon = (Taxon)event.getTaxon();
|
635
|
if (taxon == null){
|
636
|
name = event.getTaxonName();
|
637
|
if (!name.getTaxa().isEmpty()){
|
638
|
taxon = name.getTaxa().iterator().next();
|
639
|
}
|
640
|
}
|
641
|
if (taxon != null){
|
642
|
addTaxonNode(taxon, state,preferredFlag);
|
643
|
linkDeterminationEvent(state, taxon, preferredFlag, derivedUnitFacade, null, null, null);
|
644
|
}
|
645
|
}
|
646
|
|
647
|
}
|
648
|
|
649
|
/**
|
650
|
* @param names
|
651
|
* @param item
|
652
|
*/
|
653
|
private TaxonName findBestMatchingNames(GbifResponse item, SpecimenImportStateBase state) {
|
654
|
//TODO
|
655
|
if (item.getScientificName() != null){
|
656
|
|
657
|
List<TaxonName> names = findExistingNames(item.getScientificName().getNameCache(), state);
|
658
|
if (!names.isEmpty()){
|
659
|
TaxonName result = names.get(0);
|
660
|
Set<DeterminationEvent> detEvents = item.getDerivedUnitFacade().baseUnit().getDeterminations();
|
661
|
for (DeterminationEvent event:detEvents){
|
662
|
if(event.getTaxonName().getNameCache().equals(result.getNameCache()) ){
|
663
|
event.setTaxonName(result);
|
664
|
} else{
|
665
|
names = findExistingNames(event.getTaxonName().getNameCache(), state);
|
666
|
if (!names.isEmpty()){
|
667
|
event.setTaxonName(names.get(0));
|
668
|
}
|
669
|
}
|
670
|
}
|
671
|
return result;
|
672
|
}
|
673
|
}
|
674
|
return null;
|
675
|
|
676
|
}
|
677
|
|
678
|
|
679
|
|
680
|
/**
|
681
|
* @param titleCache
|
682
|
* @param state
|
683
|
* @return
|
684
|
*/
|
685
|
private List<TaxonName> findExistingNames(String nameCache, SpecimenImportStateBase state) {
|
686
|
return getNameService().findNamesByNameCache(nameCache, MatchMode.LIKE, null);
|
687
|
}
|
688
|
|
689
|
|
690
|
|
691
|
@Override
|
692
|
protected boolean isIgnore(SpecimenImportStateBase<SpecimenImportConfiguratorBase, SpecimenImportStateBase> state) {
|
693
|
return false;
|
694
|
}
|
695
|
|
696
|
|
697
|
|
698
|
/*
|
699
|
* "key": 1257570425,
|
700
|
"datasetKey": "7bd65a7a-f762-11e1-a439-00145eb45e9a",
|
701
|
"publishingOrgKey": "90fd6680-349f-11d8-aa2d-b8a03c50a862",
|
702
|
"publishingCountry": "US",
|
703
|
"protocol": "DWC_ARCHIVE",
|
704
|
"lastCrawled": "2016-06-06T11:11:35.800+0000",
|
705
|
"lastParsed": "2016-03-21T14:11:42.224+0000",
|
706
|
"extensions": { },
|
707
|
"basisOfRecord": "PRESERVED_SPECIMEN",
|
708
|
"individualCount": 1,
|
709
|
"taxonKey": 5338762,
|
710
|
"kingdomKey": 6,
|
711
|
"phylumKey": 7707728,
|
712
|
"classKey": 220,
|
713
|
"orderKey": 412,
|
714
|
"familyKey": 8798,
|
715
|
"genusKey": 2907867,
|
716
|
"speciesKey": 5338762,
|
717
|
"scientificName": "Mitchella repens L.",
|
718
|
"kingdom": "Plantae",
|
719
|
"phylum": "Tracheophyta",
|
720
|
"order": "Gentianales",
|
721
|
"family": "Rubiaceae",
|
722
|
"genus": "Mitchella",
|
723
|
"species": "Mitchella repens",
|
724
|
"genericName": "Mitchella",
|
725
|
"specificEpithet": "repens",
|
726
|
"taxonRank": "SPECIES",
|
727
|
"dateIdentified": "2005-12-31T23:00:00.000+0000",
|
728
|
"decimalLongitude": -98.70693,
|
729
|
"decimalLatitude": 20.77805,
|
730
|
"elevation": 1524.0,
|
731
|
"continent": "NORTH_AMERICA",
|
732
|
"stateProvince": "Hidalgo",
|
733
|
"year": 2006,
|
734
|
"month": 6,
|
735
|
"day": 11,
|
736
|
"eventDate": "2006-06-10T22:00:00.000+0000",
|
737
|
"issues": [
|
738
|
|
739
|
"COORDINATE_ROUNDED",
|
740
|
"GEODETIC_DATUM_ASSUMED_WGS84"
|
741
|
|
742
|
],
|
743
|
"lastInterpreted": "2016-04-17T13:34:52.325+0000",
|
744
|
"identifiers": [ ],
|
745
|
"facts": [ ],
|
746
|
"relations": [ ],
|
747
|
"geodeticDatum": "WGS84",
|
748
|
"class": "Magnoliopsida",
|
749
|
"countryCode": "MX",
|
750
|
"country": "Mexico",
|
751
|
"nomenclaturalStatus": "No opinion",
|
752
|
"rightsHolder": "Missouri Botanical Garden",
|
753
|
"identifier": "urn:catalog:MO:Tropicos:100217973",
|
754
|
"recordNumber": "Oberle 274",
|
755
|
"nomenclaturalCode": "ICNafp",
|
756
|
"county": "Metztitlán",
|
757
|
"locality": "Along trail downslope of road between Molango and Zacualtipan.",
|
758
|
"datasetName": "Tropicos",
|
759
|
"gbifID": "1257570425",
|
760
|
"collectionCode": "MO",
|
761
|
"occurrenceID": "urn:catalog:MO:Tropicos:100217973",
|
762
|
"type": "PhysicalObject",
|
763
|
"taxonID": "27902971",
|
764
|
"license": "http://creativecommons.org/licenses/by/4.0/legalcode",
|
765
|
"catalogNumber": "100217973",
|
766
|
"recordedBy": "Brad Oberle",
|
767
|
"institutionCode": "MO",
|
768
|
"ownerInstitutionCode": "MOBOT",
|
769
|
"bibliographicCitation": "http://www.tropicos.org/Specimen/100217973",
|
770
|
"identifiedBy": "B. Oberle",
|
771
|
"collectionID": "http://biocol.org/urn:lsid:biocol.org:col:15859
|
772
|
*
|
773
|
*/
|
774
|
|
775
|
|
776
|
|
777
|
}
|