Project

General

Profile

Download (70.9 KB) Statistics
| Branch: | Tag: | 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.specimen.abcd206.in;
11

    
12
import java.io.IOException;
13
import java.io.InputStream;
14
import java.net.MalformedURLException;
15
import java.net.URI;
16
import java.util.ArrayList;
17
import java.util.HashMap;
18
import java.util.List;
19
import java.util.Map;
20
import java.util.Set;
21
import java.util.UUID;
22

    
23
import org.apache.commons.lang.StringUtils;
24
import org.apache.log4j.Logger;
25
import org.springframework.stereotype.Component;
26
import org.w3c.dom.Element;
27
import org.w3c.dom.NodeList;
28

    
29
import eu.etaxonomy.cdm.api.application.ICdmRepository;
30
import eu.etaxonomy.cdm.api.facade.DerivedUnitFacade;
31
import eu.etaxonomy.cdm.common.StreamUtils;
32
import eu.etaxonomy.cdm.ext.occurrence.bioCase.BioCaseQueryServiceWrapper;
33
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
34
import eu.etaxonomy.cdm.io.common.ICdmIO;
35
import eu.etaxonomy.cdm.io.common.MapWrapper;
36
import eu.etaxonomy.cdm.io.specimen.SpecimenImportBase;
37
import eu.etaxonomy.cdm.io.specimen.SpecimenUserInteraction;
38
import eu.etaxonomy.cdm.io.specimen.UnitsGatheringArea;
39
import eu.etaxonomy.cdm.io.specimen.UnitsGatheringEvent;
40
import eu.etaxonomy.cdm.io.specimen.abcd206.in.molecular.AbcdDnaParser;
41
import eu.etaxonomy.cdm.model.agent.Institution;
42
import eu.etaxonomy.cdm.model.agent.Person;
43
import eu.etaxonomy.cdm.model.agent.Team;
44
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
45
import eu.etaxonomy.cdm.model.common.Annotation;
46
import eu.etaxonomy.cdm.model.common.CdmBase;
47
import eu.etaxonomy.cdm.model.common.IdentifiableSource;
48
import eu.etaxonomy.cdm.model.common.Language;
49
import eu.etaxonomy.cdm.model.common.LanguageString;
50
import eu.etaxonomy.cdm.model.common.OriginalSourceBase;
51
import eu.etaxonomy.cdm.model.common.OriginalSourceType;
52
import eu.etaxonomy.cdm.model.location.NamedArea;
53
import eu.etaxonomy.cdm.model.media.Media;
54
import eu.etaxonomy.cdm.model.media.Rights;
55
import eu.etaxonomy.cdm.model.media.RightsType;
56
import eu.etaxonomy.cdm.model.molecular.DnaSample;
57
import eu.etaxonomy.cdm.model.occurrence.Collection;
58
import eu.etaxonomy.cdm.model.occurrence.DerivationEvent;
59
import eu.etaxonomy.cdm.model.occurrence.DerivationEventType;
60
import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
61
import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
62
import eu.etaxonomy.cdm.model.occurrence.GatheringEvent;
63
import eu.etaxonomy.cdm.model.occurrence.MediaSpecimen;
64
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
65
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationType;
66
import eu.etaxonomy.cdm.model.reference.Reference;
67
import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
68
import eu.etaxonomy.cdm.model.taxon.Classification;
69
import eu.etaxonomy.cdm.model.term.DefinedTerm;
70
import eu.etaxonomy.cdm.model.term.DefinedTermBase;
71
import eu.etaxonomy.cdm.model.term.TermType;
72
import eu.etaxonomy.cdm.model.term.TermVocabulary;
73
import eu.etaxonomy.cdm.strategy.parser.TimePeriodParser;
74

    
75
/**
76
 * @author p.kelbert
77
 * @author p.plitzner
78
 * @author k.luther
79
 * @since 20.10.2008
80
 */
81
@Component
82
public class Abcd206Import extends SpecimenImportBase<Abcd206ImportConfigurator, Abcd206ImportState> {
83

    
84
    private static final long serialVersionUID = 3918095362150986307L;
85

    
86
    private static final UUID SPECIMEN_SCAN_TERM = UUID.fromString("acda15be-c0e2-4ea8-8783-b9b0c4ad7f03");
87

    
88
    private static final Logger logger = Logger.getLogger(Abcd206Import.class);
89

    
90
    public Abcd206Import() {
91
        super();
92
    }
93

    
94
    @Override
95
    // @SuppressWarnings("rawtypes")
96
    public void doInvoke(Abcd206ImportState state) {
97
        Abcd206ImportConfigurator config = state.getConfig();
98
        Map<String, MapWrapper<? extends CdmBase>> stores = state.getStores();
99
        MapWrapper<TeamOrPersonBase<?>> authorStore = (MapWrapper<TeamOrPersonBase<?>>) stores.get(ICdmIO.TEAM_STORE);
100
        state.setPersonStore(authorStore);
101
        MapWrapper<Reference> referenceStore = (MapWrapper<Reference>) stores.get(ICdmIO.REFERENCE_STORE);
102
        createKindOfUnitsMap(state);
103
        URI sourceUri = config.getSourceUri();
104
        try {
105
            state.setTx(startTransaction());
106
            logger.info("INVOKE Specimen Import from ABCD2.06 XML ");
107
            InputStream response = null;
108
            // init cd repository
109
            if (state.getCdmRepository() == null) {
110
                state.setCdmRepository(this);
111
            }
112
            if (config.getOccurenceQuery() != null) {
113
                BioCaseQueryServiceWrapper queryService = new BioCaseQueryServiceWrapper();
114
                try {
115

    
116
                    response = queryService.query(config.getOccurenceQuery(), sourceUri);
117
                    state.setActualAccessPoint(sourceUri);
118

    
119
                } catch (Exception e) {
120
                    logger.error("An error during ABCD import");
121
                }
122
            }
123
            SpecimenUserInteraction sui = state.getConfig().getSpecimenUserInteraction();
124

    
125
            // init import reference
126
            // List<Reference> references =
127
            // getReferenceService().list(Reference.class, null, null, null,
128
            // null);
129
            // List<Reference> references = new ArrayList<Reference>();
130

    
131
            // if (state.getConfig().isInteractWithUser()){
132
            // Map<String,Reference> refMap = new HashMap<String, Reference>();
133
            // for (Reference reference : references) {
134
            // if (! StringUtils.isBlank(reference.getTitleCache())) {
135
            // refMap.put(reference.getTitleCache(),reference);
136
            // }
137
            // }
138
            // state.setRef(sui.askForReference(refMap));
139
            //
140
            // if (state.getRef() == null){
141
            // String cla = sui.createNewReference();
142
            // if (refMap.get(cla)!= null) {
143
            // state.setRef(refMap.get(cla));
144
            // } else {
145
            // state.setRef(ReferenceFactory.newGeneric());
146
            // state.getRef().setTitle(cla);
147
            // }
148
            // }
149
            // else{
150
            // state.setRef(getReferenceService().find(state.getRef().getUuid()));
151
            // }
152
            // }else{
153
            if (state.getRef() == null) {
154
                String name = NB(state.getConfig().getSourceReferenceTitle());
155
                for (Reference reference : referenceStore.getAllValues()) {
156
                    if (!StringUtils.isBlank(reference.getTitleCache())) {
157
                        if (reference.getTitleCache().equalsIgnoreCase(name)) {
158
                            state.setRef(reference);
159
                        }
160
                    }
161
                }
162
                if (state.getRef() == null) {
163
                    if (state.getConfig().getSourceReference() != null) {
164
                        state.setRef(state.getConfig().getSourceReference());
165
                    } else {
166
                        state.setRef(ReferenceFactory.newGeneric());
167
                        state.getRef().setUri(sourceUri);
168
                        if (sourceUri != null){
169
                            state.getRef().setTitle(StringUtils.substringAfter(sourceUri.toString(), "dsa="));
170
                        }
171

    
172
                        if (!StringUtils.isBlank(state.getConfig().getSourceReferenceTitle())) {
173
                            state.getRef().setTitle(state.getConfig().getSourceReferenceTitle());
174
                        }
175
                    }
176

    
177
                }
178
            }
179
            // }
180

    
181
            save(state.getRef(), state);
182
            state.getConfig().setSourceReference(state.getRef());
183

    
184
            if (state.getConfig().getClassificationUuid() != null) {
185
                // load classification from config if it exists
186
                state.setClassification(getClassificationService().load(state.getConfig().getClassificationUuid()));
187
            }
188
            if (state.getClassification() == null) {// no existing
189
                                                    // classification was set in
190
                                                    // config
191
                List<Classification> classificationList = getClassificationService().list(Classification.class, null,
192
                        null, null, null);
193
                // get classification via user interaction
194
                if (state.getConfig().isUseClassification() && state.getConfig().isInteractWithUser()) {
195
                    Map<String, Classification> classMap = new HashMap<>();
196
                    for (Classification tree : classificationList) {
197
                        if (!StringUtils.isBlank(tree.getTitleCache())) {
198
                            classMap.put(tree.getTitleCache(), tree);
199
                        }
200
                    }
201
                    state.setClassification(sui.askForClassification(classMap));
202
                    if (state.getClassification() == null) {
203
                        String cla = sui.createNewClassification();
204
                        if (classMap.get(cla) != null) {
205
                            state.setClassification(classMap.get(cla));
206
                        } else {
207
                            state.setClassification(
208
                                    Classification.NewInstance(cla, state.getRef(), Language.DEFAULT()));
209
                        }
210
                    }
211
                    save(state.getClassification(), state);
212
                }
213
                // use default classification as the classification to import
214
                // into
215
                if (state.getClassification() == null) {
216
                    String name = NB(state.getConfig().getClassificationName());
217
                    for (Classification classif : classificationList) {
218
                        if (classif.getTitleCache() != null && classif.getTitleCache().equalsIgnoreCase(name)) {
219
                            state.setClassification(classif);
220
                        }
221
                    }
222
                    if (state.getClassification() == null) {
223
                        state.setClassification(Classification.NewInstance(name, state.getRef(), Language.DEFAULT()));
224
                        // we do not need a default classification when creating
225
                        // an empty new one
226
                        state.setDefaultClassification(state.getClassification());
227
                        save(state.getDefaultClassification(false), state);
228
                    }
229
                    save(state.getClassification(), state);
230
                }
231
            }
232

    
233
            if (response == null) {
234
                response = state.getConfig().getSource();
235
            }
236
            UnitAssociationWrapper unitAssociationWrapper = AbcdParseUtility.parseUnitsNodeList(response,
237
                    state.getReport());
238
            NodeList unitsList = unitAssociationWrapper.getAssociatedUnits();
239
            state.setPrefix(unitAssociationWrapper.getPrefix());
240

    
241
            if (unitsList != null) {
242
                String message = "nb units to insert: " + unitsList.getLength();
243
                logger.info(message);
244
                state.getConfig().getProgressMonitor().beginTask("Importing ABCD file", unitsList.getLength() + 3);
245
                updateProgress(state, message);
246

    
247
                state.setDataHolder(new Abcd206DataHolder());
248
                state.getDataHolder().reset();
249

    
250
                Abcd206XMLFieldGetter abcdFieldGetter = new Abcd206XMLFieldGetter(state.getDataHolder(),
251
                        state.getPrefix());
252
                if (config.getNomenclaturalCode() != null) {
253
                    state.getDataHolder().setNomenclatureCode(config.getNomenclaturalCode().getKey());
254
                }
255
                prepareCollectors(state, unitsList, abcdFieldGetter);
256

    
257
                // save authors
258
                getAgentService().saveOrUpdate((java.util.Collection) state.getPersonStore().objects());
259

    
260
                commitTransaction(state.getTx());
261
                state.setTx(startTransaction());
262
                if (state.getDefaultClassification(false) != null) {
263
                    state.setDefaultClassification(
264
                            getClassificationService().load(state.getDefaultClassification(false).getUuid()));
265
                }
266
                if (state.getClassification() != null) {
267
                    state.setClassification(getClassificationService().load(state.getClassification().getUuid()));
268
                }
269
                state.setAssociationRefs(new ArrayList<>());
270
                state.setDescriptionRefs(new ArrayList<>());
271
                state.setDerivedUnitSources(new ArrayList<>());
272
                for (int i = 0; i < unitsList.getLength(); i++) {
273
                    commitTransaction(state.getTx());
274
                    state.setTx(startTransaction());
275

    
276
                    if (state.getConfig().getProgressMonitor().isCanceled()) {
277
                        break;
278
                    }
279

    
280
                    state.reset();
281

    
282
                    Element item = (Element) unitsList.item(i);
283
                    Abcd206ImportParser.setUnitPropertiesXML(item, abcdFieldGetter, state);
284
                    updateProgress(state, "Importing data for unit " + state.getDataHolder().getUnitID() + " (" + i
285
                            + "/" + unitsList.getLength() + ")");
286

    
287
                    // import unit + field unit data
288
                    state.setAssociatedUnitIds(state.getDataHolder().getAssociatedUnitIds());
289
                    this.handleSingleUnit(state, item, true);
290

    
291
                }
292
                commitTransaction(state.getTx());
293
                state.setTx(startTransaction());
294
                if (state.getConfig().isDeduplicateReferences()) {
295
                    getReferenceService().deduplicate(Reference.class, null, null);
296
                }
297
                if (state.getConfig().isDeduplicateClassifications()) {
298
                    getClassificationService().deduplicate(Classification.class, null, null);
299
                }
300
            }
301
            commitTransaction(state.getTx());
302
        } catch (Exception e) {
303
            String errorDuringImport = "Exception during import!";
304
            logger.error(errorDuringImport, e);
305
            state.getReport().addException(errorDuringImport, e);
306
        } finally {
307
            state.getReport().printReport(state.getConfig().getReportUri());
308
        }
309
        if (state.getConfig().isDownloadSequenceData()) {
310
            for (URI uri:state.getSequenceDataStableIdentifier()){
311
                // Files.createDirectories(file.getParent()); // optional, make sure parent dir exists
312
                try {
313
                    StreamUtils.downloadFile(uri.toURL(), "temp");
314
                } catch (IOException e) {
315
                    // TODO Auto-generated catch block
316
                    e.printStackTrace();
317
                }
318

    
319
            }
320
        }
321

    
322
        return;
323
    }
324

    
325
    /**
326
     *
327
     */
328
    private void createKindOfUnitsMap(Abcd206ImportState state) {
329

    
330
        ICdmRepository cdmRepository = state.getConfig().getCdmAppController();
331
        if (cdmRepository == null) {
332
            cdmRepository = this;
333
        }
334

    
335
        List<DefinedTerm> terms = cdmRepository.getTermService().listByTermType(TermType.KindOfUnit, null, 0, null,
336
                null);
337
        kindOfUnitsMap = new HashMap<>();
338
        for (DefinedTerm kindOfUnit : terms) {
339
            String kindOfUnitLabel = kindOfUnit.getLabel().toLowerCase();
340
            kindOfUnitsMap.put(kindOfUnit.getLabel().toLowerCase(), kindOfUnit);
341
        }
342
    }
343

    
344
    /**
345
     * @param state
346
     * @param item
347
     */
348
    private void getSiblings(Abcd206ImportState state, Object item, DerivedUnitFacade facade) {
349
        String unitId = facade.getCatalogNumber();
350
        if (unitId == null) {
351
            unitId = facade.getAccessionNumber();
352
        }
353

    
354
        UnitAssociationParser unitParser = new UnitAssociationParser(state.getPrefix(), state.getReport(),
355
                state.getCdmRepository());
356
        UnitAssociationWrapper unitAssociationWrapper = null;
357
        for (URI accessPoint : state.getActualAccesPoint()) {
358
            unitAssociationWrapper = unitParser.parseSiblings(unitId, accessPoint);
359
            if (unitAssociationWrapper != null && unitAssociationWrapper.getAssociatedUnits() != null) {
360
                break;
361
            }
362
        }
363

    
364
        DerivedUnit currentUnit = state.getDerivedUnitBase();
365
        // DerivationEvent currentDerivedFrom = currentUnit.getDerivedFrom();
366
        FieldUnit currentFieldUnit = facade.getFieldUnit(false);
367
        if (unitAssociationWrapper != null) {
368
            NodeList associatedUnits = unitAssociationWrapper.getAssociatedUnits();
369
            if (associatedUnits != null) {
370
                for (int m = 0; m < associatedUnits.getLength(); m++) {
371
                    if (associatedUnits.item(m) instanceof Element) {
372
                        state.reset();
373
                        String associationType = AbcdParseUtility
374
                                .parseFirstTextContent(((Element) associatedUnits.item(m))
375
                                        .getElementsByTagName(state.getPrefix() + "AssociationType"));
376

    
377
                        Abcd206ImportParser.setUnitPropertiesXML((Element) associatedUnits.item(m),
378
                                new Abcd206XMLFieldGetter(state.getDataHolder(), unitAssociationWrapper.getPrefix()),
379
                                state);
380
                        // logger.debug("derived unit: " +
381
                        // state.getDerivedUnitBase().toString() + " associated
382
                        // unit: " +state.getDataHolder().getKindOfUnit() + ", "
383
                        // + state.getDataHolder().accessionNumber + ", " +
384
                        // state.getDataHolder().getRecordBasis() + ", " +
385
                        // state.getDataHolder().getUnitID());
386

    
387
                        handleSingleUnit(state, associatedUnits.item(m), false);
388

    
389
                        DerivedUnit associatedUnit = state.getDerivedUnitBase();
390
                        FieldUnit associatedFieldUnit = null;
391
                        java.util.Collection<FieldUnit> associatedFieldUnits = state.getCdmRepository()
392
                                .getOccurrenceService().findFieldUnits(associatedUnit.getUuid(), null);
393
                        // ignore field unit if associated unit has more than
394
                        // one
395
                        if (associatedFieldUnits.size() > 1) {
396
                            state.getReport()
397
                                    .addInfoMessage(String.format("%s has more than one field unit.", associatedUnit));
398
                        } else if (associatedFieldUnits.size() == 1) {
399
                            associatedFieldUnit = associatedFieldUnits.iterator().next();
400
                        }
401
                        // parent-child relation:
402
                        if (associationType.contains("individual") || associationType.contains("culture")
403
                                || associationType.contains("sample") ||  associationType.contains("isolated")) {
404
                            DerivationEvent updatedDerivationEvent = DerivationEvent.NewSimpleInstance(currentUnit,
405
                                    associatedUnit, DerivationEventType.ACCESSIONING());
406

    
407
                            updatedDerivationEvent.setDescription(associationType);
408
                            if (associatedFieldUnit != null && associatedFieldUnit != currentFieldUnit) {
409
                                associatedFieldUnit.removeDerivationEvent(updatedDerivationEvent);
410
                                state.getCdmRepository().getOccurrenceService().delete(associatedFieldUnit);
411
                            }
412
                            state.getReport().addDerivate(associatedUnit, currentUnit, state.getConfig());
413
                        }
414
                        save(associatedUnit, state);
415

    
416
                    }
417
                }
418
            }
419
        }
420
        state.reset();
421
        state.setDerivedUnitBase(currentUnit);
422

    
423
    }
424

    
425
    /**
426
     * Handle a single unit
427
     *
428
     * @param state
429
     * @param item
430
     */
431
    @Override
432
    public void handleSingleUnit(Abcd206ImportState state, Object itemObject) {
433
        handleSingleUnit(state, itemObject, true);
434
    }
435

    
436
    @SuppressWarnings("rawtypes")
437
    public void handleSingleUnit(Abcd206ImportState state, Object itemObject, boolean handleAssociatedUnits) {
438
        Element item = (Element) itemObject;
439

    
440
        Abcd206ImportConfigurator config = state.getConfig();
441
        if (logger.isDebugEnabled()) {
442
            logger.info("handleSingleUnit " + state.getRef());
443
        }
444
        try {
445
            ICdmRepository cdmAppController = state.getConfig().getCdmAppController();
446
            if (cdmAppController == null) {
447
                cdmAppController = this;
448
            }
449
            // check if unit already exists
450
            DerivedUnitFacade derivedUnitFacade = null;
451
            if (state.getConfig().isIgnoreImportOfExistingSpecimen()) {
452
                SpecimenOrObservationBase<?> existingSpecimen = findExistingSpecimen(state.getDataHolder().getUnitID(),
453
                        state);
454
                if (existingSpecimen != null && existingSpecimen.isInstanceOf(DerivedUnit.class)) {
455
                    DerivedUnit derivedUnit = HibernateProxyHelper.deproxy(existingSpecimen, DerivedUnit.class);
456
                    state.setDerivedUnitBase(derivedUnit);
457
                    derivedUnitFacade = DerivedUnitFacade.NewInstance(state.getDerivedUnitBase());
458
                    if (handleAssociatedUnits) {
459
                        importAssociatedUnits(state, item, derivedUnitFacade);
460
                    }
461

    
462
                    state.getReport().addAlreadyExistingSpecimen(SpecimenImportUtility.getUnitID(derivedUnit, config),
463
                            derivedUnit);
464

    
465
                    return;
466
                }
467
            }
468
            // TODO: implement overwrite/merge specimen
469
            // else if(state.getConfig().isOverwriteExistingSpecimens()){
470
            // Pager<SpecimenOrObservationBase> existingSpecimens =
471
            // cdmAppController.getOccurrenceService().findByTitle(config);
472
            // if(!existingSpecimens.getRecords().isEmpty()){
473
            // derivedUnitFacade = DerivedUnitFacade.NewInstance(derivedUnit);
474
            // derivedUnitBase = derivedUnitFacade.innerDerivedUnit();
475
            // fieldUnit = derivedUnitFacade.getFieldUnit(true);
476
            // }
477
            // }
478
            // import new specimen
479

    
480
            // import DNA unit
481
            if (state.getDataHolder().getKindOfUnit() != null
482
                    && state.getDataHolder().getKindOfUnit().equalsIgnoreCase("dna")) {
483
                AbcdDnaParser dnaParser = new AbcdDnaParser(state.getPrefix(), state.getReport(),
484
                        state.getCdmRepository());
485
                DnaSample dnaSample = dnaParser.parse(item, state);
486
                save(dnaSample, state);
487
                // set dna as derived unit to avoid creating an extra specimen
488
                // for this dna sample (instead just the field unit will be
489
                // created)
490
                state.setDerivedUnitBase(dnaSample);
491
                derivedUnitFacade = DerivedUnitFacade.NewInstance(state.getDerivedUnitBase());
492
            } else {
493
                // create facade
494
                derivedUnitFacade = getFacade(state);
495
                state.setDerivedUnitBase(derivedUnitFacade.innerDerivedUnit());
496

    
497
            }
498

    
499
            /**
500
             * GATHERING EVENT
501
             */
502

    
503
            // look for existing fieldUnit
504

    
505
            FieldUnit fieldUnit = state.getFieldUnit(state.getDataHolder().getFieldNumber());
506

    
507
            // gathering event
508
            UnitsGatheringEvent unitsGatheringEvent = new UnitsGatheringEvent(cdmAppController.getTermService(),
509
                    state.getDataHolder().locality, state.getDataHolder().languageIso, state.getDataHolder().longitude,
510
                    state.getDataHolder().latitude, state.getDataHolder().getGatheringCoordinateErrorMethod() , state.getDataHolder().getGatheringElevationText(),
511
                    state.getDataHolder().getGatheringElevationMin(), state.getDataHolder().getGatheringElevationMax(),
512
                    state.getDataHolder().getGatheringElevationUnit(), state.getDataHolder().getGatheringDateText(),
513
                    state.getDataHolder().getGatheringNotes(), state.getDataHolder().getGatheringMethod(),
514
                    state.getTransformer().getReferenceSystemByKey(state.getDataHolder().getGatheringSpatialDatum()),
515
                    state.getConfig());
516

    
517
            unitsGatheringEvent.setGatheringDepth(state.getDataHolder().getGatheringDepthText(),
518
                    state.getDataHolder().getGatheringDepthMin(), state.getDataHolder().getGatheringDepthMax(),
519
                    state.getDataHolder().getGatheringDepthUnit());
520
            // unitsGatheringEvent.setHeight(heightText, heightMin, heightMax,
521
            // heightUnit);
522
            if (state.getDataHolder().gatheringAgentsList.isEmpty()) {
523
                unitsGatheringEvent.setCollector(state.getPersonStore().get(state.getDataHolder().gatheringAgentsText),
524
                        config);
525
            } else {
526
                unitsGatheringEvent.setCollector(
527
                        state.getPersonStore().get(state.getDataHolder().gatheringAgentsList.toString()), config);
528
            }
529
            // count
530
            UnitsGatheringArea unitsGatheringArea = new UnitsGatheringArea();
531
            // unitsGatheringArea.setConfig(state.getConfig(),getOccurrenceService(),
532
            // getTermService());
533
            unitsGatheringArea.setParams(state.getDataHolder().isocountry, state.getDataHolder().country,
534
                    (state.getConfig()), cdmAppController.getTermService(), cdmAppController.getOccurrenceService(),
535
                    cdmAppController.getVocabularyService());
536

    
537
            DefinedTermBase<?> areaCountry = unitsGatheringArea.getCountry();
538

    
539
            // other areas
540
            unitsGatheringArea = new UnitsGatheringArea();
541
            // unitsGatheringArea.setConfig(state.getConfig(),getOccurrenceService(),getTermService());
542

    
543
            unitsGatheringArea.setAreas(state.getDataHolder().getNamedAreaList(), (state.getConfig()),
544
                    cdmAppController.getTermService(), cdmAppController.getVocabularyService());
545

    
546
            ArrayList<DefinedTermBase> nas = unitsGatheringArea.getAreas();
547
            for (DefinedTermBase namedArea : nas) {
548
                unitsGatheringEvent.addArea(namedArea);
549
            }
550

    
551
            // copy gathering event to facade
552
            GatheringEvent gatheringEvent = unitsGatheringEvent.getGatheringEvent();
553
            if (fieldUnit != null) {
554
                derivedUnitFacade.setFieldUnit(fieldUnit);
555
            }
556

    
557
            derivedUnitFacade.setLocality(gatheringEvent.getLocality());
558
            derivedUnitFacade.setExactLocation(gatheringEvent.getExactLocation());
559
            derivedUnitFacade.setCollector(gatheringEvent.getCollector());
560
            derivedUnitFacade.setCountry((NamedArea) areaCountry);
561
            derivedUnitFacade.setAbsoluteElevationText(gatheringEvent.getAbsoluteElevationText());
562
            derivedUnitFacade.setAbsoluteElevation(gatheringEvent.getAbsoluteElevation());
563
            derivedUnitFacade.setAbsoluteElevationMax(gatheringEvent.getAbsoluteElevationMax());
564
            derivedUnitFacade.setDistanceToGroundText(gatheringEvent.getDistanceToGroundText());
565
            derivedUnitFacade.setDistanceToGroundMax(gatheringEvent.getDistanceToGroundMax());
566
            derivedUnitFacade.setDistanceToGround(gatheringEvent.getDistanceToGround());
567
            derivedUnitFacade.setDistanceToWaterSurfaceText(gatheringEvent.getDistanceToWaterSurfaceText());
568
            derivedUnitFacade.setDistanceToWaterSurfaceMax(gatheringEvent.getDistanceToWaterSurfaceMax());
569
            derivedUnitFacade.setDistanceToWaterSurface(gatheringEvent.getDistanceToWaterSurface());
570
            derivedUnitFacade.setGatheringPeriod(gatheringEvent.getTimeperiod());
571
            derivedUnitFacade.setCollectingMethod(gatheringEvent.getCollectingMethod());
572

    
573
            for (DefinedTermBase<?> area : unitsGatheringArea.getAreas()) {
574
                derivedUnitFacade.addCollectingArea((NamedArea) area);
575
            }
576
            // derivedUnitFacade.addCollectingAreas(unitsGatheringArea.getAreas());
577
            // TODO exsiccatum
578

    
579
            // add fieldNumber
580
            derivedUnitFacade.setFieldNumber(NB(state.getDataHolder().getFieldNumber()));
581
            save(unitsGatheringEvent.getLocality(), state);
582

    
583
            // add unitNotes
584
            if (state.getDataHolder().getUnitNotes() != null) {
585
                derivedUnitFacade
586
                        .addAnnotation(Annotation.NewDefaultLanguageInstance(NB(state.getDataHolder().getUnitNotes())));
587
            }
588
            if (gatheringEvent.getAnnotations() != null) {
589
                for (Annotation annotation: gatheringEvent.getAnnotations()){
590
                    derivedUnitFacade.getGatheringEvent(true).
591
                        addAnnotation(annotation );
592
                }
593
            }
594

    
595
            // //add Multimedia URLs
596
            if (state.getDataHolder().getMultimediaObjects().size() != -1) {
597
                for (String multimediaObject : state.getDataHolder().getMultimediaObjects().keySet()) {
598
                    Media media;
599
                    try {
600
                        media = extractMedia(state, multimediaObject);
601

    
602

    
603

    
604
                        derivedUnitFacade.addDerivedUnitMedia(media);
605
                        if (state.getConfig().isAddMediaAsMediaSpecimen()) {
606
                            // add media also as specimen scan
607
                            MediaSpecimen mediaSpecimen = MediaSpecimen
608
                                    .NewInstance(SpecimenOrObservationType.StillImage);
609
                            mediaSpecimen.setMediaSpecimen(media);
610
                            // do it only once!!
611
                            DefinedTermBase specimenScanTerm = getTermService().load(SPECIMEN_SCAN_TERM);
612
                            if (specimenScanTerm instanceof DefinedTerm) {
613
                                mediaSpecimen.setKindOfUnit((DefinedTerm) specimenScanTerm);
614
                            }
615
                            DerivationEvent derivationEvent = DerivationEvent
616
                                    .NewInstance(DerivationEventType.PREPARATION());
617
                            derivationEvent.addDerivative(mediaSpecimen);
618
                            derivedUnitFacade.innerDerivedUnit().addDerivationEvent(derivationEvent);
619
                        }
620

    
621
                    } catch (MalformedURLException e) {
622
                        // TODO Auto-generated catch block
623
                        e.printStackTrace();
624
                    }
625

    
626
                }
627
            }
628
            // multimedia for fieldUnit
629
            if (state.getDataHolder().getGatheringMultimediaObjects().size() != -1) {
630
                for (String multimediaObject : state.getDataHolder().getGatheringMultimediaObjects().keySet()) {
631
                    Media media;
632
                    try {
633
                        media = extractMedia(state, multimediaObject);
634
                        derivedUnitFacade.addFieldObjectMedia(media);
635

    
636
                    } catch (MalformedURLException e) {
637
                        // TODO Auto-generated catch block
638
                        e.printStackTrace();
639
                    }
640

    
641
                }
642
            }
643

    
644
            // /*
645
            // * merge AND STORE DATA
646
            // */
647
            // getTermService().saveOrUpdate(areaCountry);// TODO save area
648
            // sooner
649
            //
650
            // for (NamedArea area : otherAreas) {
651
            // getTermService().saveOrUpdate(area);// merge it sooner (foreach
652
            // area)
653
            // }
654
            // save(derivedUnitFacade.getFieldUnit(false), state);
655
            if (derivedUnitFacade.getFieldUnit(false) != null) {
656
                state.setFieldUnit(derivedUnitFacade.getFieldUnit(false));
657
            }
658

    
659
            // handle collection data
660
            setCollectionData(state, derivedUnitFacade);
661

    
662
            // Reference stuff
663
            SpecimenUserInteraction sui = config.getSpecimenUserInteraction();
664
            Map<String, OriginalSourceBase<?>> sourceMap = new HashMap<>();
665

    
666
            state.getDataHolder().setDocSources(new ArrayList<>());
667
            for (String[] fullReference : state.getDataHolder().getReferenceList()) {
668
                String strReference = fullReference[0];
669
                String citationDetail = fullReference[1];
670
                String citationURL = fullReference[2];
671

    
672
                if (!citationURL.isEmpty()) {
673
                    citationDetail += ", " + citationURL;
674
                }
675

    
676
                Reference reference;
677
                if (strReference.equals(state.getRef().getTitleCache())) {
678
                    reference = state.getRef();
679
                } else {
680
                    reference = ReferenceFactory.newGeneric();
681
                    reference.setTitle(strReference);
682
                }
683

    
684
                save(reference, state);
685
                IdentifiableSource sour = getIdentifiableSource(reference, citationDetail);
686
                sour.getCitation().setUri(state.getActualAccessPoint());
687
                sour.setType(OriginalSourceType.PrimaryTaxonomicSource);
688
                try {
689
                    if (sour.getCitation() != null) {
690
                        if (StringUtils.isNotBlank(sour.getCitationMicroReference())) {
691
                            state.getDataHolder().getDocSources()
692
                                    .add(sour.getCitation().getTitleCache() + "---" + sour.getCitationMicroReference());
693
                        } else {
694
                            state.getDataHolder().getDocSources().add(sour.getCitation().getTitleCache());
695
                        }
696
                    }
697
                } catch (Exception e) {
698
                    logger.warn("oups");
699
                }
700
                derivedUnitFacade.addSource(sour);
701

    
702
            }
703
            // List<IdentifiableSource> issTmp = new
704
            // ArrayList<IdentifiableSource>();//getCommonService().list(IdentifiableSource.class,
705
            // null, null, null, null);
706
            // List<DescriptionElementSource> issTmp2 = new
707
            // ArrayList<DescriptionElementSource>();//getCommonService().list(DescriptionElementSource.class,
708
            // null, null, null, null);
709
            //
710
            // Set<OriginalSourceBase> osbSet = new
711
            // HashSet<OriginalSourceBase>();
712
            // if(issTmp2!=null) {
713
            // osbSet.addAll(issTmp2);
714
            // }
715
            // if(issTmp!=null) {
716
            // osbSet.addAll(issTmp);
717
            // }
718

    
719
            IdentifiableSource sour = getIdentifiableSource(state.getRef(), null);
720
            String idInSource = derivedUnitFacade.getAccessionNumber() != null ? derivedUnitFacade.getAccessionNumber()
721
                    : derivedUnitFacade.getCatalogNumber();
722
            sour.getCitation().setUri(state.getActualAccessPoint());
723
            sour.setIdInSource(idInSource);
724
            try {
725
                if (sour.getCitation() != null) {
726
                    if (StringUtils.isNotBlank(sour.getCitationMicroReference())) {
727
                        state.getDataHolder().getDocSources()
728
                                .add(sour.getCitation().getTitleCache() + "---" + sour.getCitationMicroReference());
729
                    } else {
730
                        state.getDataHolder().getDocSources().add(sour.getCitation().getTitleCache());
731
                    }
732
                }
733
            } catch (Exception e) {
734
                logger.warn("oups");
735
            }
736

    
737
            derivedUnitFacade.addSource(sour);
738
            // sourceMap.put(sour.getCitation().getTitleCache()+
739
            // "---"+sour.getCitationMicroReference(),sour);
740

    
741
            // if( state.getConfig().isInteractWithUser()){
742
            // List<OriginalSourceBase<?>>sources=null;
743
            // if(!state.isDerivedUnitSourcesSet()){
744
            // sources= sui.askForSource(sourceMap, "the unit
745
            // itself","",getReferenceService(),
746
            // state.getDataHolder().getDocSources());
747
            // state.setDerivedUnitSources(sources);
748
            // state.setDerivedUnitSourcesSet(true);
749
            // }
750
            // else{
751
            // sources=state.getDerivedUnitSources();
752
            // }
753
            //// for (OriginalSourceBase<?> source:sources){
754
            //// if(source.isInstanceOf(IdentifiableSource.class)){
755
            //// if(sourceNotLinkedToElement(derivedUnitFacade,source)) {
756
            //// derivedUnitFacade.addSource((IdentifiableSource)source.clone());
757
            //// }
758
            //// }else{
759
            //// if(sourceNotLinkedToElement(derivedUnitFacade,sour)) {
760
            //// derivedUnitFacade.addSource(OriginalSourceType.Import,source.getCitation(),source.getCitationMicroReference(),
761
            // ioName);
762
            //// }
763
            //// }
764
            //// }
765
            // }else{
766
            // for (OriginalSourceBase<?> sr : sourceMap.values()){
767
            // if(sr.isInstanceOf(IdentifiableSource.class)){
768
            // if(sourceNotLinkedToElement(derivedUnitFacade,sr)) {
769
            // derivedUnitFacade.addSource((IdentifiableSource)sr.clone());
770
            // }
771
            // }else{
772
            // if(sourceNotLinkedToElement(derivedUnitFacade,sr)) {
773
            // derivedUnitFacade.addSource(OriginalSourceType.Import,sr.getCitation(),sr.getCitationMicroReference(),
774
            // ioName);
775
            // }
776
            // }
777
            // }
778
            // }
779

    
780
            save(state.getDerivedUnitBase(), state);
781

    
782
            if (logger.isDebugEnabled()) {
783
                logger.info("saved ABCD specimen ...");
784
            }
785

    
786
            // handle identifications
787
            handleIdentifications(state, derivedUnitFacade);
788

    
789
            // associatedUnits
790
            if (handleAssociatedUnits) {
791
                importAssociatedUnits(state, item, derivedUnitFacade);
792
            }
793
            // siblings/ other children
794
            if (derivedUnitFacade.getType() != null
795
                    && (derivedUnitFacade.getType().equals(SpecimenOrObservationType.LivingSpecimen)
796
                            || derivedUnitFacade.getType().equals(SpecimenOrObservationType.TissueSample)
797
                            || derivedUnitFacade.getType().equals(SpecimenOrObservationType.OtherSpecimen)
798
                            || derivedUnitFacade.getType().equals(SpecimenOrObservationType.MaterialSample))
799
                    && state.getConfig().isGetSiblings()) {
800
                getSiblings(state, item, derivedUnitFacade);
801
            }
802

    
803
        } catch (Exception e) {
804
            String message = "Error when reading record! " + itemObject.toString();
805
            logger.warn(message);
806
            state.getReport().addException(message, e);
807
            e.printStackTrace();
808
            state.setUnsuccessfull();
809
        }
810

    
811
        return;
812
    }
813

    
814
    /**
815
     * @param state
816
     * @param multimediaObject
817
     * @return
818
     * @throws MalformedURLException
819
     */
820
    private Media extractMedia(Abcd206ImportState state, String multimediaObject) throws MalformedURLException {
821
        Media media;
822
        media = getImageMedia(multimediaObject, READ_MEDIA_DATA);
823
        Map<String, String> attributes = state.getDataHolder().getMultimediaObjects()
824
                .get(multimediaObject);
825
        if (attributes.containsKey("Context")) {
826
            LanguageString description = LanguageString.NewInstance(attributes.get("Context"),
827
                    Language.ENGLISH());
828
            media.addDescription(description);
829
        }
830
        if (attributes.containsKey("Comment")) {
831
            LanguageString description = LanguageString.NewInstance(attributes.get("Comment"),
832
                    Language.ENGLISH());
833
            media.addDescription(description);
834
        }
835
        if (attributes.containsKey("Creators")) {
836
            String creators = attributes.get("Creators");
837
            Person artist;
838
            Team artistTeam;
839
            String[] artists;
840
            if (creators != null) {
841
                if (creators.contains("&")) {
842
                    artists = creators.split("&");
843
                    artistTeam = new Team();
844
                    for (String creator : artists) {
845
                        artist = Person.NewTitledInstance(creator);
846
                        artistTeam.addTeamMember(artist);
847
                    }
848
                    media.setArtist(artistTeam);
849
                } else {
850

    
851
                    artist = Person.NewTitledInstance(creators);
852
                    media.setArtist(artist);
853
                }
854
            }
855

    
856
        }
857
        if (attributes.containsKey("CreateDate")) {
858
            String createDate = attributes.get("CreateDate");
859

    
860
            if (createDate != null) {
861

    
862
               media.setMediaCreated(TimePeriodParser.parseString(createDate));
863
            }
864

    
865
        }
866

    
867

    
868
        if (attributes.containsKey("License")) {
869
            String licence = attributes.get("License");
870

    
871
            if (licence != null) {
872
               Rights right = Rights.NewInstance(licence, Language.ENGLISH(), RightsType.LICENSE());
873
               media.addRights(right);
874
            }
875

    
876
        }
877
        return media;
878
    }
879

    
880
    @Override
881
    protected void importAssociatedUnits(Abcd206ImportState state, Object itemObject,
882
            DerivedUnitFacade derivedUnitFacade) {
883

    
884
        Abcd206ImportConfigurator config = state.getConfig();
885
        // import associated units
886
        FieldUnit currentFieldUnit = derivedUnitFacade.innerFieldUnit();
887
        // TODO: push state (think of implementing stack architecture for state
888
        DerivedUnit currentUnit = state.getDerivedUnitBase();
889
        DerivationEvent currentDerivedFrom = currentUnit.getDerivedFrom();
890
        URI currentAccessPoint = state.getActualAccessPoint();
891
        String currentPrefix = state.getPrefix();
892
        Element item = null;
893
        if (itemObject instanceof Element) {
894
            item = (Element) itemObject;
895
        }
896
        NodeList unitAssociationList = null;
897
        if (item != null) {
898
            unitAssociationList = item.getElementsByTagName(currentPrefix + "UnitAssociation");
899
            for (int k = 0; k < unitAssociationList.getLength(); k++) {
900
                if (unitAssociationList.item(k) instanceof Element) {
901
                    Element unitAssociation = (Element) unitAssociationList.item(k);
902
                    UnitAssociationParser unitAssociationParser = new UnitAssociationParser(currentPrefix,
903
                            state.getReport(), state.getCdmRepository());
904
                    UnitAssociationWrapper associationWrapper = unitAssociationParser.parse(unitAssociation);
905
                    if (associationWrapper != null) {
906
                        state.setActualAccessPoint(associationWrapper.getAccesPoint());
907
                        NodeList associatedUnits = associationWrapper.getAssociatedUnits();
908
                        if (associatedUnits != null) {
909
                            for (int m = 0; m < associatedUnits.getLength(); m++) {
910
                                if (associatedUnits.item(m) instanceof Element) {
911
                                    state.reset();
912
                                    state.setPrefix(associationWrapper.getPrefix());
913
                                    Abcd206ImportParser.setUnitPropertiesXML((Element) associatedUnits.item(m),
914
                                            new Abcd206XMLFieldGetter(state.getDataHolder(), state.getPrefix()), state);
915
                                    logger.debug("derived unit: " + state.getDerivedUnitBase().toString()
916
                                            + " associated unit: " + state.getDataHolder().getKindOfUnit() + ", "
917
                                            + state.getDataHolder().accessionNumber + ", "
918
                                            + state.getDataHolder().getRecordBasis() + ", "
919
                                            + state.getDataHolder().getUnitID());
920
                                    handleSingleUnit(state, associatedUnits.item(m), true);
921

    
922
                                    DerivedUnit associatedUnit = state.getDerivedUnitBase();
923
                                    FieldUnit associatedFieldUnit = null;
924
                                    java.util.Collection<FieldUnit> associatedFieldUnits = state.getCdmRepository()
925
                                            .getOccurrenceService().findFieldUnits(associatedUnit.getUuid(), null);
926
                                    // ignore field unit if associated unit has
927
                                    // more than one
928
                                    if (associatedFieldUnits.size() > 1) {
929
                                        state.getReport().addInfoMessage(
930
                                                String.format("%s has more than one field unit.", associatedUnit));
931
                                    } else if (associatedFieldUnits.size() == 1) {
932
                                        associatedFieldUnit = associatedFieldUnits.iterator().next();
933
                                    }
934

    
935
                                    // attach current unit and associated unit
936
                                    // depending on association type
937

    
938
                                    // parent-child relation:
939
                                    // copy derivation event and connect parent
940
                                    // and sub derivative
941
                                    // if(associationWrapper.getAssociationType().contains("individual")
942
                                    // ||
943
                                    // associationWrapper.getAssociationType().contains("culture")
944
                                    // ||
945
                                    // associationWrapper.getAssociationType().contains("sample")
946
                                    // ||
947
                                    // associationWrapper.getAssociationType().contains("same
948
                                    // in situ")){
949
                                    if (currentDerivedFrom == null) {
950
                                        state.getReport()
951
                                                .addInfoMessage(String.format(
952
                                                        "No derivation event found for unit %s. Defaulting to ACCESSIONING event.",
953
                                                        SpecimenImportUtility.getUnitID(currentUnit, config)));
954
                                        DerivationEvent.NewSimpleInstance(associatedUnit, currentUnit,
955
                                                DerivationEventType.ACCESSIONING());
956
                                    } else {
957
                                        DerivationEvent updatedDerivationEvent = DerivationEvent.NewSimpleInstance(
958
                                                associatedUnit, currentUnit, currentDerivedFrom.getType());
959
                                        updatedDerivationEvent.setActor(currentDerivedFrom.getActor());
960
                                        updatedDerivationEvent.setDescription(currentDerivedFrom.getDescription());
961
                                        updatedDerivationEvent.setInstitution(currentDerivedFrom.getInstitution());
962
                                        updatedDerivationEvent.setTimeperiod(currentDerivedFrom.getTimeperiod());
963

    
964
                                    }
965
                                    state.getReport().addDerivate(associatedUnit, currentUnit, config);
966
                                    // }
967
                                    // siblings relation
968
                                    // connect current unit to field unit of
969
                                    // associated unit
970
                                    // else
971
                                    // if(associationWrapper.getAssociationType().contains("population")||
972
                                    // associationWrapper.getAssociationType().contains("sample")){
973
                                    // //no associated field unit -> using
974
                                    // current one
975
                                    // if(associatedFieldUnit==null){
976
                                    // if(currentFieldUnit!=null){
977
                                    // DerivationEvent.NewSimpleInstance(currentFieldUnit,
978
                                    // associatedUnit,
979
                                    // DerivationEventType.ACCESSIONING());
980
                                    // }
981
                                    // }
982
                                    // else{
983
                                    // if(currentDerivedFrom==null){
984
                                    // state.getReport().addInfoMessage("No
985
                                    // derivation event found for unit
986
                                    // "+SpecimenImportUtility.getUnitID(currentUnit,
987
                                    // config)+". Defaulting to ACCESIONING
988
                                    // event.");
989
                                    // DerivationEvent.NewSimpleInstance(associatedFieldUnit,
990
                                    // currentUnit,
991
                                    // DerivationEventType.ACCESSIONING());
992
                                    // }
993
                                    // if(currentDerivedFrom!=null &&
994
                                    // associatedFieldUnit==currentFieldUnit){
995
                                    // DerivationEvent updatedDerivationEvent =
996
                                    // DerivationEvent.NewSimpleInstance(associatedFieldUnit,
997
                                    // currentUnit,
998
                                    // currentDerivedFrom.getType());
999
                                    // updatedDerivationEvent.setActor(currentDerivedFrom.getActor());
1000
                                    // updatedDerivationEvent.setDescription(currentDerivedFrom.getDescription());
1001
                                    // updatedDerivationEvent.setInstitution(currentDerivedFrom.getInstitution());
1002
                                    // updatedDerivationEvent.setTimeperiod(currentDerivedFrom.getTimeperiod());
1003
                                    // }
1004
                                    // }
1005
                                    // }
1006

    
1007
                                    // delete current field unit if replaced
1008
                                    if (currentFieldUnit != null && currentDerivedFrom != null
1009
                                            && currentFieldUnit.getDerivationEvents().size() == 1
1010
                                            && currentFieldUnit.getDerivationEvents().contains(currentDerivedFrom) // making
1011
                                                                                                                   // sure
1012
                                                                                                                   // that
1013
                                                                                                                   // the
1014
                                                                                                                   // field
1015
                                                                                                                   // unit
1016
                                            && currentDerivedFrom.getDerivatives().size() == 1
1017
                                            && currentDerivedFrom.getDerivatives().contains(currentUnit) // is
1018
                                                                                                         // not
1019
                                                                                                         // attached
1020
                                                                                                         // to
1021
                                                                                                         // other
1022
                                                                                                         // derived
1023
                                                                                                         // units
1024
                                            && currentDerivedFrom != currentUnit.getDerivedFrom() // <-
1025
                                                                                                  // derivation
1026
                                                                                                  // has
1027
                                                                                                  // been
1028
                                                                                                  // replaced
1029
                                                                                                  // and
1030
                                                                                                  // can
1031
                                                                                                  // be
1032
                                                                                                  // deleted
1033
                                    ) {
1034
                                        currentFieldUnit.removeDerivationEvent(currentDerivedFrom);
1035
                                        state.getCdmRepository().getOccurrenceService().delete(currentFieldUnit);
1036
                                    }
1037

    
1038
                                    save(associatedUnit, state);
1039
                                }
1040
                            }
1041
                        }
1042
                    }
1043
                }
1044
            }
1045
        }
1046
        // TODO: pop state
1047
        state.reset();
1048
        state.setDerivedUnitBase(currentUnit);
1049
        state.setActualAccessPoint(currentAccessPoint);
1050
        state.setPrefix(currentPrefix);
1051
    }
1052

    
1053
    /**
1054
     * @param derivedUnitFacade
1055
     * @param sour
1056
     * @return
1057
     */
1058
    private boolean sourceNotLinkedToElement(DerivedUnitFacade derivedUnitFacade, OriginalSourceBase<?> source) {
1059
        Set<IdentifiableSource> linkedSources = derivedUnitFacade.getSources();
1060
        for (IdentifiableSource is : linkedSources) {
1061
            if (is.getCitation() != null && source.getCitation() != null
1062
                    && is.getCitation().getTitleCache().equalsIgnoreCase(source.getCitation().getTitleCache())) {
1063
                String isDetail = is.getCitationMicroReference();
1064
                if ((StringUtils.isBlank(isDetail) && StringUtils.isBlank(source.getCitationMicroReference()))
1065
                        || (isDetail != null && isDetail.equalsIgnoreCase(source.getCitationMicroReference()))) {
1066
                    return false;
1067
                }
1068
            }
1069
        }
1070
        return true;
1071
    }
1072

    
1073
    // /**
1074
    // * @param reference
1075
    // * @param citationDetail
1076
    // * @return
1077
    // */
1078
    // private DescriptionElementSource getDescriptionSource(Reference
1079
    // reference, String citationDetail) {
1080
    //
1081
    // List<OriginalSourceBase> issTmp2 =
1082
    // getCommonService().list(DescriptionElementSource.class, null, null, null,
1083
    // null);
1084
    //
1085
    // try {
1086
    // for (OriginalSourceBase<?> osb:issTmp2){
1087
    // if (osb.getCitation().equals(reference) &&
1088
    // osb.getCitationMicroReference().equalsIgnoreCase(citationDetail)) {
1089
    // return (DescriptionElementSource) osb.clone();
1090
    // }
1091
    // }
1092
    // } catch (CloneNotSupportedException e) {
1093
    // // TODO Auto-generated catch block
1094
    // e.printStackTrace();
1095
    // }
1096
    //
1097
    // DescriptionElementSource sour =
1098
    // DescriptionElementSource.NewInstance(OriginalSourceType.Import,null,null,
1099
    // reference,citationDetail);
1100
    // return sour;
1101
    // }
1102

    
1103
    /**
1104
     * setCollectionData : store the collection object into the
1105
     * derivedUnitFacade
1106
     *
1107
     * @param state
1108
     */
1109
    protected void setCollectionData(Abcd206ImportState state, DerivedUnitFacade derivedUnitFacade) {
1110
        Abcd206ImportConfigurator config = state.getConfig();
1111
        SpecimenImportUtility.setUnitID(derivedUnitFacade.innerDerivedUnit(), state.getDataHolder().getUnitID(),
1112
                config);
1113
        if (!config.isMapUnitIdToAccessionNumber()) {
1114
            derivedUnitFacade.setAccessionNumber(NB(state.getDataHolder().accessionNumber));
1115
        }
1116
        // derivedUnitFacade.setCollectorsNumber(NB(state.getDataHolder().collectorsNumber));
1117

    
1118
        /*
1119
         * INSTITUTION & COLLECTION
1120
         */
1121
        // manage institution
1122
        Institution institution = this.getInstitution(NB(state.getDataHolder().institutionCode), state);
1123
        // manage collection
1124
        Collection collection = this.getCollection(institution, NB(state.getDataHolder().collectionCode), state);
1125
        // link specimen & collection
1126
        derivedUnitFacade.setCollection(collection);
1127
    }
1128

    
1129
    /**
1130
     * getFacade : get the DerivedUnitFacade based on the recordBasis
1131
     *
1132
     * @param state
1133
     *
1134
     * @return DerivedUnitFacade
1135
     */
1136
    @Override
1137
    protected DerivedUnitFacade getFacade(Abcd206ImportState state) {
1138
        if (logger.isDebugEnabled()) {
1139
            logger.info("getFacade()");
1140
        }
1141
        SpecimenOrObservationType type = null;
1142
        DefinedTerm kindOfUnit = null;
1143

    
1144
        // create specimen
1145
        if (NB((state.getDataHolder()).getRecordBasis()) != null) {
1146
            if (state.getDataHolder().getRecordBasis().toLowerCase().indexOf("living") > -1) {
1147
                type = SpecimenOrObservationType.LivingSpecimen;
1148
            } else if (state.getDataHolder().getRecordBasis().toLowerCase().startsWith("s")
1149
                    || state.getDataHolder().getRecordBasis().toLowerCase().indexOf("specimen") > -1) {// specimen
1150
                type = SpecimenOrObservationType.PreservedSpecimen;
1151
            } else if (state.getDataHolder().getRecordBasis().toLowerCase().startsWith("o")
1152
                    || state.getDataHolder().getRecordBasis().toLowerCase().indexOf("observation") > -1) {
1153
                if (state.getDataHolder().getRecordBasis().toLowerCase().contains("machine") && state.getDataHolder().getRecordBasis().toLowerCase().contains("observation")){
1154
                    type = SpecimenOrObservationType.MachineObservation;
1155
                }else if (state.getDataHolder().getRecordBasis().toLowerCase().contains("human") && state.getDataHolder().getRecordBasis().toLowerCase().contains("observation")){
1156
                    type = SpecimenOrObservationType.HumanObservation;
1157
                }else{
1158
                    type = SpecimenOrObservationType.Observation;
1159
                }
1160
            } else if (state.getDataHolder().getRecordBasis().toLowerCase().indexOf("fossil") > -1) {
1161
                type = SpecimenOrObservationType.Fossil;
1162
            } else if (state.getDataHolder().getRecordBasis().toLowerCase().indexOf("materialsample") > -1) {
1163
                type = SpecimenOrObservationType.MaterialSample;
1164
            } else if (state.getDataHolder().getRecordBasis().toLowerCase().indexOf("sample") > -1) {
1165
                type = SpecimenOrObservationType.TissueSample;
1166
            }
1167

    
1168
            if (type == null) {
1169
                logger.info("The basis of record does not seem to be known: " + state.getDataHolder().getRecordBasis());
1170
                type = SpecimenOrObservationType.DerivedUnit;
1171
            }
1172
        } else {
1173
            logger.info("The basis of record is null");
1174
            type = SpecimenOrObservationType.DerivedUnit;
1175
        }
1176

    
1177
        if (NB((state.getDataHolder()).getKindOfUnit()) != null) {
1178
            kindOfUnit = getKindOfUnit(state, null, state.getDataHolder().getKindOfUnit().toLowerCase(), null, null,
1179
                    null);
1180
            if (kindOfUnit == null) {
1181
                if (state.getDataHolder().getKindOfUnit().toLowerCase().indexOf("clone") > -1) {
1182
                    kindOfUnit = getKindOfUnit(state, null, "clone culture", "clone culture", "cc", null);
1183
                } else if (state.getDataHolder().getKindOfUnit().toLowerCase().startsWith("live")) {
1184
                    kindOfUnit = getKindOfUnit(state, null, "live sample", "live sample", "ls", null);
1185
                } else if (state.getDataHolder().getKindOfUnit().toLowerCase().startsWith("microscopic slide")) {
1186
                    kindOfUnit = getKindOfUnit(state, null, "microscopic slide", "microscopic slide", "ms", null);
1187
                }
1188

    
1189
                if (kindOfUnit == null) {
1190
                    logger.info("The kind of unit does not seem to be known: " + state.getDataHolder().getKindOfUnit());
1191

    
1192
                }
1193
            }
1194
        } else {
1195
            logger.info("The kind of unit is null");
1196

    
1197
        }
1198
        DerivedUnitFacade derivedUnitFacade = DerivedUnitFacade.NewInstance(type);
1199
        derivedUnitFacade.setFieldUnit(state.getFieldUnit(state.getDataHolder().getFieldNumber()));
1200
        derivedUnitFacade.setDerivedUnitKindOfUnit(kindOfUnit);
1201
       // derivedUnitFacade.setDerivedUnitKindOfUnit(kindOfUnit);
1202
        return derivedUnitFacade;
1203
    }
1204

    
1205
    private void getCollectorsFromXML(Element root, Abcd206XMLFieldGetter abcdFieldGetter, Abcd206ImportState state) {
1206
        NodeList group;
1207

    
1208
        group = root.getChildNodes();
1209
        for (int i = 0; i < group.getLength(); i++) {
1210
            if (group.item(i).getNodeName().equals(state.getPrefix() + "Identifications")) {
1211
                group = group.item(i).getChildNodes();
1212
                break;
1213
            }
1214
        }
1215
        // state.getDataHolder().gatheringAgents = "";
1216

    
1217
        abcdFieldGetter.getType(root);
1218
        abcdFieldGetter.getGatheringPeople(root);
1219
    }
1220

    
1221
    // private void compareABCDtoCDM(URI urlFileName, List<String> knownElts,
1222
    // Abcd206XMLFieldGetter abcdFieldGetter) {
1223
    // try {
1224
    // DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
1225
    // DocumentBuilder constructeur = factory.newDocumentBuilder();
1226
    // URL url = urlFileName.toURL();
1227
    // Object o = url.getContent();
1228
    // InputStream is = (InputStream) o;
1229
    // Document document = constructeur.parse(is);
1230
    // Element root = document.getDocumentElement();
1231
    // abcdFieldGetter.traverse(root);
1232
    // }
1233
    // catch (ParserConfigurationException e){
1234
    // e.printStackTrace();
1235
    // }
1236
    // catch (SAXException e) {
1237
    // e.printStackTrace();
1238
    // }
1239
    // catch (IOException e) {
1240
    // e.printStackTrace();
1241
    // }
1242
    // Set<String> elts = state.getDataHolder().allABCDelements.keySet();
1243
    // Iterator<String> it = elts.iterator();
1244
    // String elt;
1245
    // while (it.hasNext()) {
1246
    // elt = it.next();
1247
    // if (knownElts.indexOf(elt) == -1) {
1248
    // if(DEBUG) {
1249
    // logger.info("Unmerged ABCD element: " + elt + " - "+
1250
    // state.getDataHolder().allABCDelements.get(elt));
1251
    // }
1252
    // }
1253
    // }
1254
    // }
1255

    
1256
    /**
1257
     * Load the list of names from the ABCD file and save them
1258
     *
1259
     * @param state
1260
     *            : the current ABCD import state
1261
     * @param unitsList
1262
     *            : the unit list from the ABCD file
1263
     * @param abcdFieldGetter
1264
     *            : the ABCD parser
1265
     */
1266
    private void prepareCollectors(Abcd206ImportState state, NodeList unitsList,
1267
            Abcd206XMLFieldGetter abcdFieldGetter) {
1268

    
1269
        TeamOrPersonBase<?> teamOrPerson = null;
1270
        Team team = null;
1271
        // ImportHelper.setOriginalSource(teamOrPerson,
1272
        // state.getConfig().getSourceReference(), collector, "Collector");
1273
        for (int i = 0; i < unitsList.getLength(); i++) {
1274
            this.getCollectorsFromXML((Element) unitsList.item(i), abcdFieldGetter, state);
1275
            if (!(state.getDataHolder().gatheringAgentsList.isEmpty())) {
1276
                if (state.getDataHolder().gatheringAgentsList.size() == 1) {
1277
                    teamOrPerson = parseAuthorString(state.getDataHolder().gatheringAgentsList.get(0));
1278
                } else {
1279
                    team = new Team();
1280
                    for (String collector : state.getDataHolder().gatheringAgentsList) {
1281
                        teamOrPerson = parseAuthorString(collector);
1282
                        if (teamOrPerson instanceof Person) {
1283
                            team.addTeamMember((Person) teamOrPerson);
1284
                        } else {
1285
                            for (Person person : ((Team) teamOrPerson).getTeamMembers()) {
1286
                                team.addTeamMember(person);
1287
                            }
1288
                        }
1289
                    }
1290
                }
1291
                if (!state.getPersonStore().containsId(state.getDataHolder().gatheringAgentsList.toString())) {
1292
                    state.getPersonStore().put(state.getDataHolder().gatheringAgentsList.toString(), teamOrPerson);
1293
                    if (logger.isDebugEnabled()) {
1294
                        logger.debug("Stored author " + state.getDataHolder().gatheringAgentsList.toString());
1295
                    }
1296
                    logger.warn("Not imported author with duplicated aut_id "
1297
                            + state.getDataHolder().gatheringAgentsList.toString());
1298
                }
1299
            }
1300
            if (!StringUtils.isBlank(state.getDataHolder().gatheringAgentsText)
1301
                    && state.getDataHolder().gatheringAgentsList.isEmpty()) {
1302
                teamOrPerson = parseAuthorString(state.getDataHolder().gatheringAgentsText);
1303
//                if (teamOrPerson instanceof Person) {
1304
//                    //team.addTeamMember((Person) teamOrPerson);
1305
//                } else {
1306
//                    team = new Team();
1307
//                    for (Person person : ((Team) teamOrPerson).getTeamMembers()) {
1308
//                        team.addTeamMember(person);
1309
//                    }
1310
//                }
1311
                if (!state.getPersonStore().containsId(state.getDataHolder().gatheringAgentsText)) {
1312
                    state.getPersonStore().put(state.getDataHolder().gatheringAgentsText, teamOrPerson);
1313
                    if (logger.isDebugEnabled()) {
1314
                        logger.debug("Stored author " + state.getDataHolder().gatheringAgentsText);
1315
                    }
1316
                    logger.warn("Not imported author with duplicated aut_id "
1317
                            + state.getDataHolder().gatheringAgentsList.toString());
1318
                }
1319
            }
1320

    
1321
        }
1322

    
1323
        // List<String> collectorsU = new ArrayList<String>(new
1324
        // HashSet<String>(collectors));
1325
        // List<String> teamsU = new ArrayList<String>(new
1326
        // HashSet<String>(teams));
1327
        //
1328
        //
1329
        // //existing teams in DB
1330
        // Map<String,Team> titleCacheTeam = new HashMap<String, Team>();
1331
        // List<UuidAndTitleCache<Team>> hiberTeam = new
1332
        // ArrayList<UuidAndTitleCache<Team>>();//getAgentService().getTeamUuidAndTitleCache();
1333

    
1334
        // Set<UUID> uuids = new HashSet<UUID>();
1335
        // for (UuidAndTitleCache<Team> hibernateT:hiberTeam){
1336
        // uuids.add(hibernateT.getUuid());
1337
        // }
1338
        // if (!uuids.isEmpty()){
1339
        // List<AgentBase> existingTeams = getAgentService().find(uuids);
1340
        // for (AgentBase<?> existingP:existingTeams){
1341
        // titleCacheTeam.put(existingP.getTitleCache(),CdmBase.deproxy(existingP,Team.class));
1342
        // }
1343
        // }
1344

    
1345
        // Map<String,UUID> teamMap = new HashMap<String, UUID>();
1346
        // for (UuidAndTitleCache<Team> uuidt:hiberTeam){
1347
        // teamMap.put(uuidt.getTitleCache(), uuidt.getUuid());
1348
        // }
1349

    
1350
        // existing persons in DB
1351
        // List<UuidAndTitleCache<Person>> hiberPersons = new
1352
        // ArrayList<UuidAndTitleCache<Person>>();//getAgentService().getPersonUuidAndTitleCache();
1353
        // Map<String,Person> titleCachePerson = new HashMap<String, Person>();
1354
        // uuids = new HashSet<UUID>();
1355
        // for (UuidAndTitleCache<Person> hibernateP:hiberPersons){
1356
        // uuids.add(hibernateP.getUuid());
1357
        // }
1358
        //
1359
        // if (!uuids.isEmpty()){
1360
        // List<AgentBase> existingPersons = getAgentService().find(uuids);
1361
        // for (AgentBase<?> existingP:existingPersons){
1362
        // titleCachePerson.put(existingP.getTitleCache(),CdmBase.deproxy(existingP,Person.class));
1363
        // }
1364
        // }
1365
        //
1366
        // Map<String,UUID> personMap = new HashMap<String, UUID>();
1367
        // for (UuidAndTitleCache<Person> person:hiberPersons){
1368
        // personMap.put(person.getTitleCache(), person.getUuid());
1369
        // }
1370
        //
1371
        // java.util.Collection<Person> personToadd = new ArrayList<Person>();
1372
        // java.util.Collection<Team> teamToAdd = new ArrayList<Team>();
1373
        //
1374
        // for (String collector:collectorsU){
1375
        // Person p = Person.NewInstance();
1376
        // p.setTitleCache(collector,true);
1377
        // if (!personMap.containsKey(p.getTitleCache())){
1378
        // personToadd.add(p);
1379
        // }
1380
        // }
1381
        // for (String team:teamsU){
1382
        // Team p = Team.NewInstance();
1383
        // p.setTitleCache(team,true);
1384
        // if (!teamMap.containsKey(p.getTitleCache())){
1385
        // teamToAdd.add(p);
1386
        // }
1387
        // }
1388
        //
1389
        // if(!personToadd.isEmpty()){
1390
        // for (Person agent: personToadd){
1391
        // save(agent, state);
1392
        // titleCachePerson.put(agent.getTitleCache(),CdmBase.deproxy(agent,
1393
        // Person.class) );
1394
        // }
1395
        // }
1396
        //
1397
        // Person ptmp ;
1398
        // Map <String,Integer>teamdone = new HashMap<String, Integer>();
1399
        // for (List<String> collteam: collectorinteams){
1400
        // if (!teamdone.containsKey(StringUtils.join(collteam.toArray(),"-"))){
1401
        // Team team = new Team();
1402
        // boolean em =true;
1403
        // for (String collector:collteam){
1404
        // ptmp = Person.NewInstance();
1405
        // ptmp.setTitleCache(collector,true);
1406
        // Person p2 = titleCachePerson.get(ptmp.getTitleCache());
1407
        // team.addTeamMember(p2);
1408
        // em=false;
1409
        // }
1410
        // if (!em) {
1411
        // teamToAdd.add(team);
1412
        // }
1413
        // teamdone.put(StringUtils.join(collteam.toArray(),"-"),0);
1414
        // }
1415
        // }
1416
        //
1417
        // if(!teamToAdd.isEmpty()){
1418
        // for (Team agent: teamToAdd){
1419
        // save(agent, state);
1420
        // titleCacheTeam.put(agent.getTitleCache(), CdmBase.deproxy(
1421
        // agent,Team.class) );
1422
        // }
1423
        // }
1424

    
1425
        // ((Abcd206ImportConfigurator)
1426
        // state.getConfig()).setTeams(titleCacheTeam);
1427
        // ((Abcd206ImportConfigurator)
1428
        // state.getConfig()).setPersons(titleCachePerson);
1429
    }
1430

    
1431
    @Override
1432
    protected boolean doCheck(Abcd206ImportState state) {
1433
        logger.warn("Checking not yet implemented for " + this.getClass().getSimpleName());
1434
        return true;
1435
    }
1436

    
1437
    @Override
1438
    protected boolean isIgnore(Abcd206ImportState state) {
1439
        return false;
1440
    }
1441

    
1442
    @Override
1443
    protected DefinedTerm getKindOfUnit(Abcd206ImportState state, UUID uuid, String label, String description,
1444
            String labelAbbrev, TermVocabulary<DefinedTerm> voc) {
1445

    
1446
        DefinedTerm unit = null;
1447

    
1448
        if (uuid == null) {
1449
            unit = this.kindOfUnitsMap.get(label.toLowerCase());
1450
        } else {
1451
            unit = state.getKindOfUnit(uuid);
1452

    
1453
        }
1454
        if (unit == null) {
1455
            unit = (DefinedTerm) getTermService().find(uuid);
1456
            if (unit == null) {
1457
                if (uuid == null) {
1458
                    uuid = UUID.randomUUID();
1459
                }
1460
                unit = DefinedTerm.NewKindOfUnitInstance(description, label, labelAbbrev);
1461
                unit.setUuid(uuid);
1462
                if (voc == null) {
1463
                    boolean isOrdered = false;
1464
                    voc = getVocabulary(TermType.KindOfUnit, uuidUserDefinedKindOfUnitVocabulary,
1465
                            "User defined vocabulary for kind-of-units", "User Defined Measurement kind-of-units", null,
1466
                            null, isOrdered, unit);
1467
                }
1468
                voc.addTerm(unit);
1469
                getTermService().save(unit);
1470
            }
1471
            state.putKindOfUnit(unit);
1472
            kindOfUnitsMap.put(unit.getLabel().toLowerCase(), unit);
1473
        }
1474
        return unit;
1475
    }
1476

    
1477
}
(2-2/15)