Project

General

Profile

Download (77.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.api.service.DeleteResult;
32
import eu.etaxonomy.cdm.api.service.config.SpecimenDeleteConfigurator;
33
import eu.etaxonomy.cdm.common.StreamUtils;
34
import eu.etaxonomy.cdm.ext.occurrence.bioCase.BioCaseQueryServiceWrapper;
35
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
36
import eu.etaxonomy.cdm.io.common.ICdmIO;
37
import eu.etaxonomy.cdm.io.common.MapWrapper;
38
import eu.etaxonomy.cdm.io.specimen.SpecimenImportBase;
39
import eu.etaxonomy.cdm.io.specimen.SpecimenUserInteraction;
40
import eu.etaxonomy.cdm.io.specimen.UnitsGatheringArea;
41
import eu.etaxonomy.cdm.io.specimen.UnitsGatheringEvent;
42
import eu.etaxonomy.cdm.io.specimen.abcd206.in.molecular.AbcdDnaParser;
43
import eu.etaxonomy.cdm.model.agent.Institution;
44
import eu.etaxonomy.cdm.model.agent.Person;
45
import eu.etaxonomy.cdm.model.agent.Team;
46
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
47
import eu.etaxonomy.cdm.model.common.Annotation;
48
import eu.etaxonomy.cdm.model.common.CdmBase;
49
import eu.etaxonomy.cdm.model.common.IdentifiableSource;
50
import eu.etaxonomy.cdm.model.common.Language;
51
import eu.etaxonomy.cdm.model.common.LanguageString;
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.OriginalSourceBase;
67
import eu.etaxonomy.cdm.model.reference.Reference;
68
import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
69
import eu.etaxonomy.cdm.model.taxon.Classification;
70
import eu.etaxonomy.cdm.model.term.DefinedTerm;
71
import eu.etaxonomy.cdm.model.term.DefinedTermBase;
72
import eu.etaxonomy.cdm.model.term.TermType;
73
import eu.etaxonomy.cdm.model.term.TermVocabulary;
74
import eu.etaxonomy.cdm.strategy.parser.TimePeriodParser;
75

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

    
85
    private static final long serialVersionUID = 3918095362150986307L;
86

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

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

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

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

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

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

    
126
            if (state.getRef() == null) {
127
                String name = NB(state.getConfig().getSourceReferenceTitle());
128
                for (Reference reference : referenceStore.getAllValues()) {
129
                    if (!StringUtils.isBlank(reference.getTitleCache())) {
130
                        if (reference.getTitleCache().equalsIgnoreCase(name)) {
131
                            state.setRef(reference);
132

    
133
                        }
134
                    }
135
                }
136
                if (state.getRef() == null) {
137
                    if (state.getConfig().getSourceReference() != null) {
138
                        state.setRef(state.getConfig().getSourceReference());
139
                        state.addImportReference(state.getRef());
140

    
141
                    } else {
142
                        state.setRef(ReferenceFactory.newGeneric());
143
                        state.getRef().setUri(sourceUri);
144

    
145
                        if (sourceUri != null) {
146
                            state.getRef().setTitle(StringUtils.substringAfter(sourceUri.toString(), "dsa="));
147
                        }
148

    
149
                        if (!StringUtils.isBlank(state.getConfig().getSourceReferenceTitle())) {
150
                            state.getRef().setTitle(state.getConfig().getSourceReferenceTitle());
151
                        }
152
                        state.addImportReference(state.getRef());
153
                    }
154

    
155
                }
156
            }
157
            // }
158

    
159
            save(state.getRef(), state);
160
            state.getConfig().setSourceReference(state.getRef());
161

    
162
            if (state.getConfig().getClassificationUuid() != null) {
163
                // load classification from config if it exists
164
                state.setClassification(getClassificationService().load(state.getConfig().getClassificationUuid()));
165
            }
166
            if (state.getClassification() == null) {// no existing
167
                                                    // classification was set in
168
                                                    // config
169
                List<Classification> classificationList = getClassificationService().list(Classification.class, null,
170
                        null, null, null);
171
                // get classification via user interaction
172
                if (state.getConfig().isUseClassification() && state.getConfig().isInteractWithUser()) {
173
                    Map<String, Classification> classMap = new HashMap<>();
174
                    for (Classification tree : classificationList) {
175
                        if (!StringUtils.isBlank(tree.getTitleCache())) {
176
                            classMap.put(tree.getTitleCache(), tree);
177
                        }
178
                    }
179
                    state.setClassification(sui.askForClassification(classMap));
180
                    if (state.getClassification() == null) {
181
                        String cla = sui.createNewClassification();
182
                        if (classMap.get(cla) != null) {
183
                            state.setClassification(classMap.get(cla));
184
                        } else {
185
                            state.setClassification(
186
                                    Classification.NewInstance(cla, state.getRef(), Language.DEFAULT()));
187
                        }
188
                    }
189
                    save(state.getClassification(), state);
190
                }
191
                // use default classification as the classification to import
192
                // into
193
                if (state.getClassification() == null) {
194
                    String name = NB(state.getConfig().getClassificationName());
195
                    for (Classification classif : classificationList) {
196
                        if (classif.getTitleCache() != null && classif.getTitleCache().equalsIgnoreCase(name)) {
197
                            state.setClassification(classif);
198
                        }
199
                    }
200
                    if (state.getClassification() == null) {
201
                        state.setClassification(Classification.NewInstance(name, state.getRef(), Language.DEFAULT()));
202
                        // we do not need a default classification when creating
203
                        // an empty new one
204
                        state.setDefaultClassification(state.getClassification());
205
                        save(state.getDefaultClassification(false), state);
206
                    }
207
                    save(state.getClassification(), state);
208
                }
209
            }
210

    
211
            if (response == null) {
212
                response = state.getConfig().getSource();
213
            }
214
            UnitAssociationWrapper unitAssociationWrapper = AbcdParseUtility.parseUnitsNodeList(response,
215
                    state.getReport());
216
            NodeList unitsList = unitAssociationWrapper.getAssociatedUnits();
217
            state.setPrefix(unitAssociationWrapper.getPrefix());
218

    
219
            if (unitsList != null) {
220
                String message = "nb units to insert: " + unitsList.getLength();
221
                logger.info(message);
222
                state.getConfig().getProgressMonitor().beginTask("Importing ABCD file", unitsList.getLength() + 3);
223
                updateProgress(state, message);
224

    
225
                state.setDataHolder(new Abcd206DataHolder());
226
                state.getDataHolder().reset();
227

    
228
                Abcd206XMLFieldGetter abcdFieldGetter = new Abcd206XMLFieldGetter(state.getDataHolder(),
229
                        state.getPrefix());
230
                if (config.getNomenclaturalCode() != null) {
231
                    state.getDataHolder().setNomenclatureCode(config.getNomenclaturalCode().getKey());
232
                }
233
                prepareCollectors(state, unitsList, abcdFieldGetter);
234

    
235
                // save authors
236
                getAgentService().saveOrUpdate((java.util.Collection) state.getPersonStore().objects());
237

    
238
                commitTransaction(state.getTx());
239
                state.setTx(startTransaction());
240
                if (state.getDefaultClassification(false) != null) {
241
                    state.setDefaultClassification(
242
                            getClassificationService().load(state.getDefaultClassification(false).getUuid()));
243
                }
244
                if (state.getClassification() != null) {
245
                    state.setClassification(getClassificationService().load(state.getClassification().getUuid()));
246
                }
247
                state.setAssociationRefs(new ArrayList<>());
248
                state.setDescriptionRefs(new ArrayList<>());
249
                state.setDerivedUnitSources(new ArrayList<>());
250
                for (int i = 0; i < unitsList.getLength(); i++) {
251
                    commitTransaction(state.getTx());
252
                    state.setTx(startTransaction());
253

    
254
                    if (state.getConfig().getProgressMonitor().isCanceled()) {
255
                        break;
256
                    }
257

    
258
                    state.reset();
259
                    state.getDataHolder().setNomenclatureCode(state.getConfig().getNomenclaturalCode()!= null? state.getConfig().getNomenclaturalCode().getKey() : null);
260
                    Element item = (Element) unitsList.item(i);
261
                    Abcd206ImportParser.setUnitPropertiesXML(item, abcdFieldGetter, state);
262
                    updateProgress(state, "Importing data for unit " + state.getDataHolder().getUnitID() + " (" + i
263
                            + "/" + unitsList.getLength() + ")");
264

    
265
                    // import unit + field unit data
266
                    state.setAssociatedUnitIds(state.getDataHolder().getAssociatedUnitIds());
267

    
268
                    this.handleSingleUnit(state, item, true);
269
                    state.setLastFieldUnit(null);
270

    
271
                }
272
                commitTransaction(state.getTx());
273
                state.setTx(startTransaction());
274
                if (state.getConfig().isDeduplicateReferences()) {
275
                    getReferenceService().deduplicate(Reference.class, null, null);
276
                }
277
                if (state.getConfig().isDeduplicateClassifications()) {
278
                    getClassificationService().deduplicate(Classification.class, null, null);
279
                }
280
            }
281
            commitTransaction(state.getTx());
282
        } catch (Exception e) {
283
            String errorDuringImport = "Exception during import!";
284
            logger.error(errorDuringImport, e);
285
            state.getReport().addException(errorDuringImport, e);
286
        } finally {
287
            state.getReport().printReport(state.getConfig().getReportUri());
288
        }
289
        if (state.getConfig().isDownloadSequenceData()) {
290
            for (URI uri : state.getSequenceDataStableIdentifier()) {
291
                // Files.createDirectories(file.getParent()); // optional, make
292
                // sure parent dir exists
293
                try {
294
                    StreamUtils.downloadFile(uri.toURL(), "temp");
295
                } catch (IOException e) {
296
                    // TODO Auto-generated catch block
297
                    e.printStackTrace();
298
                }
299

    
300
            }
301
        }
302

    
303
        return;
304
    }
305

    
306
    /**
307
     *
308
     */
309
    private void createKindOfUnitsMap(Abcd206ImportState state) {
310

    
311
        ICdmRepository cdmRepository = state.getConfig().getCdmAppController();
312
        if (cdmRepository == null) {
313
            cdmRepository = this;
314
        }
315

    
316
        List<DefinedTerm> terms = cdmRepository.getTermService().listByTermType(TermType.KindOfUnit, null, 0, null,
317
                null);
318
        kindOfUnitsMap = new HashMap<>();
319
        for (DefinedTerm kindOfUnit : terms) {
320
            if (kindOfUnit != null && kindOfUnit.getLabel() != null) {
321
                String kindOfUnitLabel = kindOfUnit.getLabel().toLowerCase();
322
                kindOfUnitsMap.put(kindOfUnitLabel, kindOfUnit);
323
            }
324

    
325
        }
326
    }
327

    
328
    /**
329
     * @param state
330
     * @param item
331
     */
332
    private void getSiblings(Abcd206ImportState state, Object item, DerivedUnitFacade facade) {
333
        String unitId = facade.getCatalogNumber();
334
        if (unitId == null) {
335
            unitId = facade.getAccessionNumber();
336
        }
337
        if (unitId == null){
338
            unitId = facade.getBarcode();
339
        }
340

    
341
        UnitAssociationParser unitParser = new UnitAssociationParser(state.getPrefix(), state.getReport(),
342
                state.getCdmRepository());
343
        UnitAssociationWrapper unitAssociationWrapper = null;
344
        for (URI accessPoint : state.getAllAccesPoint()) {
345
            unitAssociationWrapper = unitParser.parseSiblings(unitId, accessPoint);
346
            if (unitAssociationWrapper != null && unitAssociationWrapper.getAssociatedUnits() != null) {
347
                break;
348
            }
349
        }
350

    
351
        DerivedUnit currentUnit = state.getDerivedUnitBase();
352
        // DerivationEvent currentDerivedFrom = currentUnit.getDerivedFrom();
353
        FieldUnit currentFieldUnit = facade.getFieldUnit(false);
354
        if (unitAssociationWrapper != null) {
355
            NodeList associatedUnits = unitAssociationWrapper.getAssociatedUnits();
356
            if (associatedUnits != null) {
357
                for (int m = 0; m < associatedUnits.getLength(); m++) {
358
                    if (associatedUnits.item(m) instanceof Element) {
359
                        state.reset();
360
                        String associationType = AbcdParseUtility
361
                                .parseFirstTextContent(((Element) associatedUnits.item(m))
362
                                        .getElementsByTagName(state.getPrefix() + "AssociationType"));
363

    
364
                        Abcd206ImportParser.setUnitPropertiesXML((Element) associatedUnits.item(m),
365
                                new Abcd206XMLFieldGetter(state.getDataHolder(), unitAssociationWrapper.getPrefix()),
366
                                state);
367
                        // logger.debug("derived unit: " +
368
                        // state.getDerivedUnitBase().toString() + " associated
369
                        // unit: " +state.getDataHolder().getKindOfUnit() + ", "
370
                        // + state.getDataHolder().accessionNumber + ", " +
371
                        // state.getDataHolder().getRecordBasis() + ", " +
372
                        // state.getDataHolder().getUnitID());
373

    
374
                        handleSingleUnit(state, associatedUnits.item(m), false);
375

    
376
                        DerivedUnit associatedUnit = state.getDerivedUnitBase();
377
                        FieldUnit associatedFieldUnit = null;
378
                        commitTransaction(state.getTx());
379
                        state.setTx(startTransaction());
380
                        java.util.Collection<FieldUnit> associatedFieldUnits = null;
381
                        try {
382
                            associatedFieldUnits = state.getCdmRepository().getOccurrenceService()
383
                                    .findFieldUnits(associatedUnit.getUuid(), null);
384
                        } catch (NullPointerException e) {
385
                            logger.error("Search for associated field unit creates a NPE" + e.getMessage());
386
                        }
387
                        // ignore field unit if associated unit has more than
388
                        // one
389
                        if (associatedFieldUnits != null && associatedFieldUnits.size() > 1) {
390
                            state.getReport()
391
                                    .addInfoMessage(String.format("%s has more than one field unit.", associatedUnit));
392
                        } else if (associatedFieldUnits != null && associatedFieldUnits.size() == 1) {
393
                            associatedFieldUnit = associatedFieldUnits.iterator().next();
394
                        }
395
                        // parent-child relation:
396
                        if (associationType != null && (associationType.contains("individual") || associationType.contains("culture")
397
                                || associationType.contains("sample") || associationType.contains("isolated"))) {
398
                            DerivationEvent updatedDerivationEvent = DerivationEvent.NewSimpleInstance(currentUnit,
399
                                    associatedUnit, DerivationEventType.ACCESSIONING());
400

    
401
                            updatedDerivationEvent.setDescription(associationType);
402
                            if (associatedFieldUnit != null && associatedFieldUnit != currentFieldUnit && currentFieldUnit != null) {
403
                                // associatedFieldUnit.removeDerivationEvent(updatedDerivationEvent);
404
                                // save(associatedFieldUnit, state);
405
                                // if
406
                                // (associatedFieldUnit.getDerivationEvents().isEmpty()){
407
                                SpecimenDeleteConfigurator config = new SpecimenDeleteConfigurator();
408
                                config.setDeleteChildren(false);
409
                                DeleteResult result = state.getCdmRepository().getOccurrenceService()
410
                                        .delete(associatedFieldUnit, config);
411
                                if (!result.isOk()) {
412
                                    logger.debug("Deletion of field unit " + associatedFieldUnit.getFieldNumber()
413
                                            + " not successfull");
414
                                }
415
                                state.setFieldUnit(currentFieldUnit);
416

    
417
                                // }
418

    
419
                            }
420
                            state.getReport().addDerivate(associatedUnit, currentUnit, state.getConfig());
421
                        }
422
                        save(associatedUnit, state);
423

    
424
                    }
425
                }
426
            }
427
        }
428
        state.reset();
429
        state.setDerivedUnitBase(currentUnit);
430

    
431
    }
432

    
433
    /**
434
     * Handle a single unit
435
     *
436
     * @param state
437
     * @param item
438
     */
439
    @Override
440
    public void handleSingleUnit(Abcd206ImportState state, Object itemObject) {
441
        handleSingleUnit(state, itemObject, true);
442
    }
443

    
444
    @SuppressWarnings("rawtypes")
445
    public void handleSingleUnit(Abcd206ImportState state, Object itemObject, boolean handleAssociatedUnits) {
446
        Element item = (Element) itemObject;
447

    
448
        Abcd206ImportConfigurator config = state.getConfig();
449
        if (logger.isDebugEnabled()) {
450
            logger.info("handleSingleUnit " + state.getRef());
451
        }
452
        try {
453
            ICdmRepository cdmAppController = state.getConfig().getCdmAppController();
454
            if (cdmAppController == null) {
455
                cdmAppController = this;
456
            }
457
            // check if unit already exists
458
            DerivedUnitFacade derivedUnitFacade = null;
459
            if (state.getConfig().isIgnoreImportOfExistingSpecimen() && state.getDataHolder().getUnitID() != null) {
460

    
461
                SpecimenOrObservationBase<?> existingSpecimen = findExistingSpecimen(state.getDataHolder().getUnitID(),
462
                        state);
463
                if (existingSpecimen != null && existingSpecimen.isInstanceOf(DerivedUnit.class)) {
464
                    DerivedUnit derivedUnit = HibernateProxyHelper.deproxy(existingSpecimen, DerivedUnit.class);
465
                    state.setDerivedUnitBase(derivedUnit);
466
                    derivedUnitFacade = DerivedUnitFacade.NewInstance(state.getDerivedUnitBase());
467
                    if (handleAssociatedUnits) {
468
                        importAssociatedUnits(state, item, derivedUnitFacade);
469
                    }
470
                    if (state.getConfig().getDnaSoure() != null) {
471
                        importAssociatedDna(state, item, derivedUnitFacade);
472
                    }
473

    
474
                    state.getReport().addAlreadyExistingSpecimen(SpecimenImportUtility.getUnitID(derivedUnit, config),
475
                            derivedUnit);
476

    
477
                    return;
478
                }
479
            } else {
480
                System.err.println("dataholder does not contain unit id");
481
            }
482

    
483

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

    
502
            }
503

    
504
            /**
505
             * GATHERING EVENT
506
             */
507

    
508
            // look for existing fieldUnit
509
            FieldUnit fieldUnit = null;
510
            if (StringUtils.isNotBlank(state.getDataHolder().getFieldNumber())){
511
                fieldUnit = state.getFieldUnit(state.getDataHolder().getFieldNumber());
512
                if (fieldUnit != null){
513
                    state.setLastFieldUnit(fieldUnit);
514
                }
515
            }else{
516
                fieldUnit = state.getLastFieldUnit();
517

    
518
            }
519
            if (fieldUnit == null){
520
                fieldUnit = FieldUnit.NewInstance();
521
                fieldUnit.setFieldNumber(state.getDataHolder().getFieldNumber());
522
                state.setLastFieldUnit(fieldUnit);
523
            }
524

    
525
            // gathering event
526
            UnitsGatheringEvent unitsGatheringEvent = new UnitsGatheringEvent(cdmAppController.getTermService(),
527
                    state.getDataHolder().locality, state.getDataHolder().languageIso, state.getDataHolder().longitude,
528
                    state.getDataHolder().latitude, state.getDataHolder().getGatheringCoordinateErrorMethod(),
529
                    state.getDataHolder().getGatheringElevationText(), state.getDataHolder().getGatheringElevationMin(),
530
                    state.getDataHolder().getGatheringElevationMax(), state.getDataHolder().getGatheringElevationUnit(),
531
                    state.getDataHolder().getGatheringDateText(), state.getDataHolder().getGatheringNotes(),
532
                    state.getDataHolder().getGatheringMethod(),
533
                    state.getTransformer().getReferenceSystemByKey(state.getDataHolder().getGatheringSpatialDatum()),
534
                    state.getConfig());
535

    
536
            unitsGatheringEvent.setGatheringDepth(state.getDataHolder().getGatheringDepthText(),
537
                    state.getDataHolder().getGatheringDepthMin(), state.getDataHolder().getGatheringDepthMax(),
538
                    state.getDataHolder().getGatheringDepthUnit());
539
            // unitsGatheringEvent.setHeight(heightText, heightMin, heightMax,
540
            // heightUnit);
541
            if (state.getDataHolder().gatheringAgentsList.isEmpty()) {
542
                TeamOrPersonBase team = state.getPersonStore().get(state.getDataHolder().gatheringAgentsText);
543
                if (team == null){
544
                    team = parseAuthorString(state.getDataHolder().gatheringAgentsText);
545
                    if (team != null){
546
                        state.getPersonStore().put(team.getTitleCache(), team);
547
                    }
548
                }
549
                if (team != null){
550
                    unitsGatheringEvent.setCollector(team,
551
                            config);
552
                }
553

    
554

    
555
            } else {
556
                TeamOrPersonBase team = state.getPersonStore().get(state.getDataHolder().gatheringAgentsList.toString());
557
                if (team == null){
558
                    team = parseAuthorString(state.getDataHolder().gatheringAgentsList.toString());
559
                    if (team != null){
560
                        state.getPersonStore().put(team.getTitleCache(), team);
561
                    }
562

    
563
                }
564
                if (team != null){
565
                    unitsGatheringEvent.setCollector(team,
566
                            config);
567
                }
568
            }
569
            // count
570
            UnitsGatheringArea unitsGatheringArea = new UnitsGatheringArea();
571
            // unitsGatheringArea.setConfig(state.getConfig(),getOccurrenceService(),
572
            // getTermService());
573
            unitsGatheringArea.setParams(state.getDataHolder().isocountry, state.getDataHolder().country,
574
                    (state.getConfig()), cdmAppController.getTermService(),
575
                    cdmAppController.getVocabularyService());
576

    
577
            DefinedTermBase<?> areaCountry = unitsGatheringArea.getCountry();
578

    
579
            // other areas
580
            unitsGatheringArea = new UnitsGatheringArea();
581
            // unitsGatheringArea.setConfig(state.getConfig(),getOccurrenceService(),getTermService());
582

    
583
            unitsGatheringArea.setAreas(state.getDataHolder().getNamedAreaList(), (state.getConfig()),
584
                    cdmAppController.getTermService(), cdmAppController.getVocabularyService());
585

    
586
            ArrayList<DefinedTermBase> nas = unitsGatheringArea.getAreas();
587
            for (DefinedTermBase namedArea : nas) {
588
                unitsGatheringEvent.addArea(namedArea);
589
            }
590

    
591
            // copy gathering event to facade
592
            GatheringEvent gatheringEvent = unitsGatheringEvent.getGatheringEvent();
593
            if (fieldUnit != null) {
594
                derivedUnitFacade.setFieldUnit(fieldUnit);
595
                if (derivedUnitFacade.getGatheringPeriod() == null && gatheringEvent.getTimeperiod() != null){
596
                    derivedUnitFacade.setGatheringPeriod(gatheringEvent.getTimeperiod());
597
                }
598
                if (derivedUnitFacade.getLocality() == null && gatheringEvent.getLocality() != null){
599
                    derivedUnitFacade.setLocality(gatheringEvent.getLocality());
600
                }
601
                if (derivedUnitFacade.getExactLocation() == null && gatheringEvent.getExactLocation() != null){
602
                    derivedUnitFacade.setExactLocation(gatheringEvent.getExactLocation());
603
                }
604

    
605
                if (derivedUnitFacade.getCollector() == null && gatheringEvent.getCollector() != null){
606
                    derivedUnitFacade.setCollector(gatheringEvent.getCollector());
607
                }
608
                if (derivedUnitFacade.getCountry() == null && areaCountry != null){
609
                    derivedUnitFacade.setCountry((NamedArea) areaCountry);
610
                }
611
                if (StringUtils.isBlank(derivedUnitFacade.getAbsoluteElevationText()) && StringUtils.isNotBlank(gatheringEvent.getAbsoluteElevationText())){
612
                    derivedUnitFacade.setAbsoluteElevationText(gatheringEvent.getAbsoluteElevationText());
613
                }
614
                if (derivedUnitFacade.getAbsoluteElevation() == null && gatheringEvent.getAbsoluteElevation() != null){
615
                    derivedUnitFacade.setAbsoluteElevation(gatheringEvent.getAbsoluteElevation());
616
                }
617
                if (derivedUnitFacade.getAbsoluteElevationMaximum() == null && gatheringEvent.getAbsoluteElevationMax() != null){
618
                    derivedUnitFacade.setAbsoluteElevationMax(gatheringEvent.getAbsoluteElevationMax());
619
                }
620
                if (StringUtils.isBlank(derivedUnitFacade.getDistanceToGroundText()) && StringUtils.isNotBlank(gatheringEvent.getDistanceToGroundText())){
621
                    derivedUnitFacade.setDistanceToGroundText(gatheringEvent.getDistanceToGroundText());
622
                }
623
                if (derivedUnitFacade.getDistanceToGroundMax() == null && gatheringEvent.getDistanceToGroundMax() != null){
624
                    derivedUnitFacade.setDistanceToGroundMax(gatheringEvent.getDistanceToGroundMax());
625
                }
626
                if (derivedUnitFacade.getDistanceToGround() == null && gatheringEvent.getDistanceToGround() != null){
627
                    derivedUnitFacade.setDistanceToGround(gatheringEvent.getDistanceToGround());
628
                }
629
                if (StringUtils.isBlank(derivedUnitFacade.getDistanceToWaterSurfaceText()) && StringUtils.isNotBlank(gatheringEvent.getDistanceToWaterSurfaceText())){
630
                    derivedUnitFacade.setDistanceToWaterSurfaceText(gatheringEvent.getDistanceToWaterSurfaceText());
631
                }
632
                if (derivedUnitFacade.getDistanceToWaterSurfaceMax() == null && gatheringEvent.getDistanceToWaterSurfaceMax() != null){
633
                    derivedUnitFacade.setDistanceToWaterSurfaceMax(gatheringEvent.getDistanceToWaterSurfaceMax());
634
                }
635
                if (derivedUnitFacade.getDistanceToWaterSurface() == null && gatheringEvent.getDistanceToWaterSurface() != null){
636
                    derivedUnitFacade.setDistanceToWaterSurface(gatheringEvent.getDistanceToWaterSurface());
637
                }
638
                if (derivedUnitFacade.getGatheringPeriod() == null && gatheringEvent.getTimeperiod() != null){
639
                    derivedUnitFacade.setGatheringPeriod(gatheringEvent.getTimeperiod());
640
                }
641
                if (derivedUnitFacade.getCollectingMethod() == null && gatheringEvent.getCollectingMethod() != null){
642
                    derivedUnitFacade.setCollectingMethod(gatheringEvent.getCollectingMethod());
643
                }
644
                for (DefinedTermBase<?> area : unitsGatheringArea.getAreas()) {
645
                    derivedUnitFacade.addCollectingArea((NamedArea) area);
646
                }
647
             // add unitNotes
648
                if (state.getDataHolder().getUnitNotes() != null) {
649
                    derivedUnitFacade
650
                            .addAnnotation(Annotation.NewDefaultLanguageInstance(NB(state.getDataHolder().getUnitNotes())));
651
                }
652
                if (gatheringEvent.getAnnotations() != null) {
653
                    for (Annotation annotation : gatheringEvent.getAnnotations()) {
654
                        derivedUnitFacade.getGatheringEvent(true).addAnnotation(annotation);
655
                    }
656
                }
657

    
658
            }else{
659
//TODO??
660
            }
661

    
662

    
663

    
664

    
665
            // derivedUnitFacade.addCollectingAreas(unitsGatheringArea.getAreas());
666
            // TODO exsiccatum
667

    
668
            // add fieldNumber
669
            String fieldNumber = null;
670
            if (derivedUnitFacade.getFieldUnit(false) != null) {
671
                fieldNumber = derivedUnitFacade.getFieldUnit(false).getFieldNumber();
672
                if (fieldNumber == null){
673
                    derivedUnitFacade.setFieldNumber(NB(state.getDataHolder().getFieldNumber()));
674
                }
675
            }
676

    
677
            save(unitsGatheringEvent.getLocality(), state);
678

    
679

    
680

    
681

    
682
            // //add Multimedia URLs
683
            if (state.getDataHolder().getMultimediaObjects().size() != -1) {
684
                for (String multimediaObject : state.getDataHolder().getMultimediaObjects().keySet()) {
685
                    Media media;
686
                    try {
687
                        media = extractMedia(state, multimediaObject);
688
                        if (media == null) {
689
                            continue;
690
                        }
691
                        derivedUnitFacade.addDerivedUnitMedia(media);
692
                        if (state.getConfig().isAddMediaAsMediaSpecimen()) {
693
                            // add media also as specimen scan
694
                            MediaSpecimen mediaSpecimen = MediaSpecimen
695
                                    .NewInstance(SpecimenOrObservationType.StillImage);
696
                            mediaSpecimen.setMediaSpecimen(media);
697
                            // do it only once!!
698
                            DefinedTermBase specimenScanTerm = getTermService().load(SPECIMEN_SCAN_TERM);
699
                            if (specimenScanTerm instanceof DefinedTerm) {
700
                                mediaSpecimen.setKindOfUnit((DefinedTerm) specimenScanTerm);
701
                            }
702
                            DerivationEvent derivationEvent = DerivationEvent
703
                                    .NewInstance(DerivationEventType.PREPARATION());
704
                            derivationEvent.addDerivative(mediaSpecimen);
705
                            derivedUnitFacade.innerDerivedUnit().addDerivationEvent(derivationEvent);
706
                        }
707

    
708
                    } catch (MalformedURLException e) {
709
                        // TODO Auto-generated catch block
710
                        e.printStackTrace();
711
                    }
712

    
713
                }
714
            }
715
            // multimedia for fieldUnit
716
            if (state.getDataHolder().getGatheringMultimediaObjects().size() != -1) {
717
                for (String multimediaObject : state.getDataHolder().getGatheringMultimediaObjects().keySet()) {
718
                    Media media;
719
                    try {
720
                        media = extractMedia(state, multimediaObject);
721
                        if (media == null) {
722
                            continue;
723
                        }
724
                        derivedUnitFacade.addFieldObjectMedia(media);
725

    
726
                    } catch (MalformedURLException e) {
727
                        // TODO Auto-generated catch block
728
                        e.printStackTrace();
729
                    }
730

    
731
                }
732
            }
733

    
734

    
735
            if (derivedUnitFacade.getFieldUnit(false) != null) {
736
                state.setFieldUnit(derivedUnitFacade.getFieldUnit(false));
737
            }
738

    
739
            // handle collection data
740
            setCollectionData(state, derivedUnitFacade);
741

    
742
            // Reference stuff
743
            SpecimenUserInteraction sui = config.getSpecimenUserInteraction();
744
            Map<String, OriginalSourceBase<?>> sourceMap = new HashMap<>();
745

    
746
            state.getDataHolder().setDocSources(new ArrayList<>());
747

    
748

    
749

    
750
            IdentifiableSource sour = getIdentifiableSource(state.getImportReference(state.getActualAccessPoint()), null);
751
            String idInSource = derivedUnitFacade.getAccessionNumber() != null ? derivedUnitFacade.getAccessionNumber()
752
                    : derivedUnitFacade.getCatalogNumber() != null ? derivedUnitFacade.getCatalogNumber() : derivedUnitFacade.getBarcode();
753
            //sour.getCitation().setUri(state.getActualAccessPoint());
754
            sour.setIdInSource(idInSource);
755
            try {
756
                if (sour.getCitation() != null) {
757
                    if (StringUtils.isNotBlank(sour.getCitationMicroReference())) {
758
                        state.getDataHolder().getDocSources()
759
                                .add(sour.getCitation().getTitleCache() + "---" + sour.getCitationMicroReference());
760
                    } else {
761
                        state.getDataHolder().getDocSources().add(sour.getCitation().getTitleCache());
762
                    }
763
                }
764
            } catch (Exception e) {
765
                logger.warn("oups");
766
            }
767

    
768
            derivedUnitFacade.addSource(sour);
769

    
770

    
771
            save(state.getDerivedUnitBase(), state);
772

    
773
            if (logger.isDebugEnabled()) {
774
                logger.info("saved ABCD specimen ...");
775
            }
776

    
777
            // handle identifications
778
            handleIdentifications(state, derivedUnitFacade);
779

    
780
            // associatedUnits
781
            if (handleAssociatedUnits) {
782
                importAssociatedUnits(state, item, derivedUnitFacade);
783
            }
784
            if (state.getConfig().getDnaSoure() != null ) {
785
                importAssociatedDna(state, item, derivedUnitFacade);
786
            }
787
            // siblings/ other children
788
            if (derivedUnitFacade.getType() != null
789
                    && (derivedUnitFacade.getType().equals(SpecimenOrObservationType.LivingSpecimen)
790
                            || derivedUnitFacade.getType().equals(SpecimenOrObservationType.TissueSample)
791
                            || derivedUnitFacade.getType().equals(SpecimenOrObservationType.OtherSpecimen)
792
                            || derivedUnitFacade.getType().equals(SpecimenOrObservationType.MaterialSample))
793
                    && state.getConfig().isGetSiblings()) {
794
                getSiblings(state, item, derivedUnitFacade);
795
            }
796

    
797
        } catch (Exception e) {
798
            String message = "Error when reading record! " + itemObject.toString();
799
            logger.warn(message);
800
            state.getReport().addException(message, e);
801
            e.printStackTrace();
802
            state.setUnsuccessfull();
803
        }
804

    
805
        return;
806
    }
807

    
808
    /**
809
     * @param state
810
     * @param multimediaObject
811
     * @return
812
     * @throws MalformedURLException
813
     */
814
    private Media extractMedia(Abcd206ImportState state, String multimediaObject) throws MalformedURLException {
815
        Media media;
816
        media = getImageMedia(multimediaObject, READ_MEDIA_DATA);
817

    
818
        Map<String, String> attributes = state.getDataHolder().getMultimediaObjects().get(multimediaObject);
819
        if (attributes == null) {
820
            attributes = state.getDataHolder().getGatheringMultimediaObjects().get(multimediaObject);
821
            if (attributes == null) {
822
                logger.error(multimediaObject + " does not exist in dataHolder");
823
                state.getResult().addError(multimediaObject + " does not exist in dataHolder");
824
                return null;
825
            }
826
        }
827
        if (attributes.containsKey("Context")) {
828
            LanguageString description = LanguageString.NewInstance(attributes.get("Context"), Language.ENGLISH());
829
            media.addDescription(description);
830
        }
831
        if (attributes.containsKey("Comment")) {
832
            LanguageString description = LanguageString.NewInstance(attributes.get("Comment"), 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
        if (attributes.containsKey("License")) {
868
            String licence = attributes.get("License");
869

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

    
875
        }
876
        return media;
877
    }
878

    
879
    @Override
880
    protected void importAssociatedUnits(Abcd206ImportState state, Object itemObject,
881
            DerivedUnitFacade derivedUnitFacade) {
882
        SpecimenDeleteConfigurator deleteConfig = new SpecimenDeleteConfigurator();
883
        deleteConfig.setDeleteChildren(false);
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: " +
916
                                    // state.getDerivedUnitBase().toString()
917
                                    // + " associated unit: " +
918
                                    // state.getDataHolder().getKindOfUnit() +
919
                                    // ", "
920
                                    // + state.getDataHolder().accessionNumber +
921
                                    // ", "
922
                                    // + state.getDataHolder().getRecordBasis()
923
                                    // + ", "
924
                                    // + state.getDataHolder().getUnitID());
925
                                    handleSingleUnit(state, associatedUnits.item(m), true);
926

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

    
940
                                    // attach current unit and associated unit
941
                                    // depending on association type
942

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

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

    
1012
                                    // delete current field unit if replaced
1013
                                    if (currentFieldUnit != null && currentDerivedFrom != null
1014
                                            && currentFieldUnit.getDerivationEvents().size() == 1
1015
                                            && currentFieldUnit.getDerivationEvents().contains(currentDerivedFrom) // making
1016
                                                                                                                   // sure
1017
                                                                                                                   // that
1018
                                                                                                                   // the
1019
                                                                                                                   // field
1020
                                                                                                                   // unit
1021
                                            && currentDerivedFrom.getDerivatives().size() == 1
1022
                                            && currentDerivedFrom.getDerivatives().contains(currentUnit) // is
1023
                                                                                                         // not
1024
                                                                                                         // attached
1025
                                                                                                         // to
1026
                                                                                                         // other
1027
                                                                                                         // derived
1028
                                                                                                         // units
1029
                                            && currentDerivedFrom != currentUnit.getDerivedFrom() // <-
1030
                                                                                                  // derivation
1031
                                                                                                  // has
1032
                                                                                                  // been
1033
                                                                                                  // replaced
1034
                                                                                                  // and
1035
                                                                                                  // can
1036
                                                                                                  // be
1037
                                                                                                  // deleted
1038
                                    ) {
1039
                                        currentFieldUnit.removeDerivationEvent(currentDerivedFrom);
1040
                                        if (associatedFieldUnit != null && associatedFieldUnit.getGatheringEvent() != null && associatedFieldUnit.getGatheringEvent().getActor() == null && currentFieldUnit.getGatheringEvent().getActor() != null){
1041
                                            associatedFieldUnit.getGatheringEvent().setActor(currentFieldUnit.getGatheringEvent().getActor());
1042
                                        }
1043
                                        if (associatedFieldUnit != null && associatedFieldUnit.getFieldNumber() == null && currentFieldUnit.getFieldNumber() != null) {
1044
                                            associatedFieldUnit.setFieldNumber(currentFieldUnit.getFieldNumber());
1045
                                        }
1046

    
1047
                                        if (currentFieldUnit.getDerivationEvents().isEmpty()) {
1048
                                            DeleteResult result = state.getCdmRepository().getOccurrenceService()
1049
                                                    .delete(currentFieldUnit, deleteConfig);
1050

    
1051

    
1052
                                        } else {
1053

    
1054
                                            logger.debug("there are still derivation events in fieldUnit "
1055
                                                    + currentFieldUnit.getId());
1056
                                        }
1057

    
1058
                                    }
1059
                                    state.setLastFieldUnit(associatedFieldUnit);
1060
                                    save(associatedUnit, state);
1061
                                }
1062
                            }
1063
                        }
1064
                    }
1065
                }
1066
            }
1067
        }
1068
        // TODO: pop state
1069
        state.reset();
1070
        state.setDerivedUnitBase(currentUnit);
1071
        state.setActualAccessPoint(currentAccessPoint);
1072
        state.setPrefix(currentPrefix);
1073
    }
1074

    
1075
    private void importAssociatedDna(Abcd206ImportState state, Object itemObject, DerivedUnitFacade derivedUnitFacade) {
1076
        URI dnaSource = state.getConfig().getDnaSoure();
1077
        String unitId = derivedUnitFacade.getCatalogNumber();
1078
        if (unitId == null) {
1079
            unitId = derivedUnitFacade.getAccessionNumber();
1080
        }
1081
        if (unitId == null) {
1082
            unitId = derivedUnitFacade.getBarcode();
1083
        }
1084

    
1085
        UnitAssociationParser unitParser = new UnitAssociationParser(state.getPrefix(), state.getReport(),
1086
                state.getCdmRepository());
1087
        UnitAssociationWrapper unitAssociationWrapper = null;
1088

    
1089
        unitAssociationWrapper = unitParser.parseSiblings(unitId, dnaSource);
1090

    
1091
        DerivedUnit currentUnit = state.getDerivedUnitBase();
1092
        // DerivationEvent currentDerivedFrom = currentUnit.getDerivedFrom();
1093
        FieldUnit currentFieldUnit = derivedUnitFacade.getFieldUnit(false);
1094
        if (unitAssociationWrapper != null) {
1095
            NodeList associatedUnits = unitAssociationWrapper.getAssociatedUnits();
1096
            if (associatedUnits != null) {
1097
                for (int m = 0; m < associatedUnits.getLength(); m++) {
1098
                    if (associatedUnits.item(m) instanceof Element) {
1099
                        state.reset();
1100
                        String associationType = AbcdParseUtility
1101
                                .parseFirstTextContent(((Element) associatedUnits.item(m))
1102
                                        .getElementsByTagName(unitAssociationWrapper.getPrefix() + "AssociationType"));
1103
                        Abcd206XMLFieldGetter fieldGetter = new Abcd206XMLFieldGetter(state.getDataHolder(), unitAssociationWrapper.getPrefix());
1104
                        Abcd206ImportParser.setUnitPropertiesXML((Element) associatedUnits.item(m),
1105
                                fieldGetter,
1106
                                state);
1107
                        // logger.debug("derived unit: " +
1108
                        // state.getDerivedUnitBase().toString() + " associated
1109
                        // unit: " +state.getDataHolder().getKindOfUnit() + ", "
1110
                        // + state.getDataHolder().accessionNumber + ", " +
1111
                        // state.getDataHolder().getRecordBasis() + ", " +
1112
                        // state.getDataHolder().getUnitID());
1113
                        URI lastAccessPoint = state.getActualAccessPoint();
1114
                        state.setActualAccessPoint(dnaSource);
1115
                        String oldPrefix = state.getPrefix();
1116
                        state.setPrefix(unitAssociationWrapper.getPrefix());
1117
                        handleSingleUnit(state, associatedUnits.item(m), false);
1118
                        state.setActualAccessPoint(lastAccessPoint);
1119
                        state.setPrefix(oldPrefix);
1120
                        DerivedUnit associatedUnit = state.getDerivedUnitBase();
1121
                        FieldUnit associatedFieldUnit = null;
1122
                        java.util.Collection<FieldUnit> associatedFieldUnits = state.getCdmRepository()
1123
                                .getOccurrenceService().findFieldUnits(associatedUnit.getUuid(), null);
1124
                        // ignore field unit if associated unit has more than
1125
                        // one
1126
                        if (associatedFieldUnits.size() > 1) {
1127
                            state.getReport()
1128
                                    .addInfoMessage(String.format("%s has more than one field unit.", associatedUnit));
1129
                        } else if (associatedFieldUnits.size() == 1) {
1130
                            associatedFieldUnit = associatedFieldUnits.iterator().next();
1131
                        }
1132
                        // parent-child relation:
1133
                        if (associationType != null && (associationType.contains("individual")
1134
                                || associationType.contains("culture") || associationType.contains("sample")
1135
                                || associationType.contains("isolated"))) {
1136
                            DerivationEvent updatedDerivationEvent = DerivationEvent.NewSimpleInstance(currentUnit,
1137
                                    associatedUnit, DerivationEventType.ACCESSIONING());
1138

    
1139
                            updatedDerivationEvent.setDescription(associationType);
1140
                            if (associatedFieldUnit != null && !associatedFieldUnit.equals(currentFieldUnit) && currentFieldUnit != null) {
1141
                                associatedFieldUnit.removeDerivationEvent(updatedDerivationEvent);
1142
                                if ((associatedFieldUnit.getGatheringEvent() != null && associatedFieldUnit.getGatheringEvent().getActor() != null) && (currentFieldUnit.getGatheringEvent() != null && currentFieldUnit.getGatheringEvent().getActor() == null)){
1143
                                    currentFieldUnit.getGatheringEvent().setActor(associatedFieldUnit.getGatheringEvent().getActor());
1144
                                }
1145
                                if (associatedFieldUnit.getFieldNumber() != null && currentFieldUnit.getFieldNumber() == null){
1146
                                    currentFieldUnit.setFieldNumber(associatedFieldUnit.getFieldNumber());
1147
                                }
1148

    
1149

    
1150

    
1151
                                SpecimenDeleteConfigurator deleteConfig = new SpecimenDeleteConfigurator();
1152
                                deleteConfig.setDeleteChildren(false);
1153
                                DeleteResult result = state.getCdmRepository().getOccurrenceService()
1154
                                        .delete(associatedFieldUnit, deleteConfig);
1155
                                state.setFieldUnit(currentFieldUnit);
1156

    
1157
                                // }
1158
                                if (updatedDerivationEvent.getOriginals().isEmpty()) {
1159
                                    // state.getCdmRepository().getOccurrenceService().deleteDerivationEvent(updatedDerivationEvent);
1160
                                }
1161
                            }else{
1162
                                state.setLastFieldUnit(associatedFieldUnit);
1163
                            }
1164
                            state.getReport().addDerivate(associatedUnit, currentUnit, state.getConfig());
1165
                        }
1166
                        save(associatedUnit, state);
1167

    
1168
                    }
1169
                }
1170
            }
1171
        }
1172
        state.reset();
1173
        state.setDerivedUnitBase(currentUnit);
1174

    
1175
    }
1176

    
1177
    /**
1178
     * @param derivedUnitFacade
1179
     * @param sour
1180
     * @return
1181
     */
1182
    private boolean sourceNotLinkedToElement(DerivedUnitFacade derivedUnitFacade, OriginalSourceBase<?> source) {
1183
        Set<IdentifiableSource> linkedSources = derivedUnitFacade.getSources();
1184
        for (IdentifiableSource is : linkedSources) {
1185
            if (is.getCitation() != null && source.getCitation() != null
1186
                    && is.getCitation().getTitleCache().equalsIgnoreCase(source.getCitation().getTitleCache())) {
1187
                String isDetail = is.getCitationMicroReference();
1188
                if ((StringUtils.isBlank(isDetail) && StringUtils.isBlank(source.getCitationMicroReference()))
1189
                        || (isDetail != null && isDetail.equalsIgnoreCase(source.getCitationMicroReference()))) {
1190
                    return false;
1191
                }
1192
            }
1193
        }
1194
        return true;
1195
    }
1196

    
1197

    
1198

    
1199
    /**
1200
     * setCollectionData : store the collection object into the
1201
     * derivedUnitFacade
1202
     *
1203
     * @param state
1204
     */
1205
    protected void setCollectionData(Abcd206ImportState state, DerivedUnitFacade derivedUnitFacade) {
1206
        Abcd206ImportConfigurator config = state.getConfig();
1207
        SpecimenImportUtility.setUnitID(derivedUnitFacade.innerDerivedUnit(), state.getDataHolder().getUnitID(),
1208
                config);
1209
        if (!config.isMapUnitIdToAccessionNumber()) {
1210
            derivedUnitFacade.setAccessionNumber(NB(state.getDataHolder().accessionNumber));
1211
        }
1212
        // derivedUnitFacade.setCollectorsNumber(NB(state.getDataHolder().collectorsNumber));
1213

    
1214
        /*
1215
         * INSTITUTION & COLLECTION
1216
         */
1217
        // manage institution
1218
        Institution institution = this.getInstitution(NB(state.getDataHolder().institutionCode), state);
1219
        // manage collection
1220
        Collection collection = this.getCollection(institution, NB(state.getDataHolder().collectionCode), state);
1221
        // link specimen & collection
1222
        derivedUnitFacade.setCollection(collection);
1223
    }
1224

    
1225
    /**
1226
     * getFacade : get the DerivedUnitFacade based on the recordBasis
1227
     *
1228
     * @param state
1229
     *
1230
     * @return DerivedUnitFacade
1231
     */
1232
    @Override
1233
    protected DerivedUnitFacade getFacade(Abcd206ImportState state) {
1234
        if (logger.isDebugEnabled()) {
1235
            logger.info("getFacade()");
1236
        }
1237
        SpecimenOrObservationType type = null;
1238
        DefinedTerm kindOfUnit = null;
1239

    
1240
        // create specimen
1241
        if (NB((state.getDataHolder()).getRecordBasis()) != null) {
1242
            if (state.getDataHolder().getRecordBasis().toLowerCase().indexOf("living") > -1) {
1243
                type = SpecimenOrObservationType.LivingSpecimen;
1244
            } else if (state.getDataHolder().getRecordBasis().toLowerCase().startsWith("s")
1245
                    || state.getDataHolder().getRecordBasis().toLowerCase().indexOf("specimen") > -1) {// specimen
1246
                type = SpecimenOrObservationType.PreservedSpecimen;
1247
            } else if (state.getDataHolder().getRecordBasis().toLowerCase().startsWith("o")
1248
                    || state.getDataHolder().getRecordBasis().toLowerCase().indexOf("observation") > -1) {
1249
                if (state.getDataHolder().getRecordBasis().toLowerCase().contains("machine")
1250
                        && state.getDataHolder().getRecordBasis().toLowerCase().contains("observation")) {
1251
                    type = SpecimenOrObservationType.MachineObservation;
1252
                } else if (state.getDataHolder().getRecordBasis().toLowerCase().contains("human")
1253
                        && state.getDataHolder().getRecordBasis().toLowerCase().contains("observation")) {
1254
                    type = SpecimenOrObservationType.HumanObservation;
1255
                } else {
1256
                    type = SpecimenOrObservationType.Observation;
1257
                }
1258
            } else if (state.getDataHolder().getRecordBasis().toLowerCase().indexOf("fossil") > -1) {
1259
                type = SpecimenOrObservationType.Fossil;
1260
            } else if (state.getDataHolder().getRecordBasis().toLowerCase().indexOf("materialsample") > -1) {
1261
                type = SpecimenOrObservationType.MaterialSample;
1262
            } else if (state.getDataHolder().getRecordBasis().toLowerCase().indexOf("sample") > -1) {
1263
                type = SpecimenOrObservationType.TissueSample;
1264
            }
1265

    
1266
            if (type == null) {
1267
                logger.info("The basis of record does not seem to be known: " + state.getDataHolder().getRecordBasis());
1268
                type = SpecimenOrObservationType.DerivedUnit;
1269
            }
1270
        } else {
1271
            logger.info("The basis of record is null");
1272
            type = SpecimenOrObservationType.DerivedUnit;
1273
        }
1274

    
1275
        if (NB((state.getDataHolder()).getKindOfUnit()) != null) {
1276
            kindOfUnit = getKindOfUnit(state, null, state.getDataHolder().getKindOfUnit().toLowerCase(), null, null,
1277
                    null);
1278
            if (kindOfUnit == null) {
1279
                if (state.getDataHolder().getKindOfUnit().toLowerCase().indexOf("clone") > -1) {
1280
                    kindOfUnit = getKindOfUnit(state, null, "clone culture", "clone culture", "cc", null);
1281
                } else if (state.getDataHolder().getKindOfUnit().toLowerCase().startsWith("live")) {
1282
                    kindOfUnit = getKindOfUnit(state, null, "live sample", "live sample", "ls", null);
1283
                } else if (state.getDataHolder().getKindOfUnit().toLowerCase().startsWith("microscopic slide")) {
1284
                    kindOfUnit = getKindOfUnit(state, null, "microscopic slide", "microscopic slide", "ms", null);
1285
                }
1286

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

    
1290
                }
1291
            }
1292
        } else {
1293
            logger.info("The kind of unit is null");
1294

    
1295
        }
1296
        DerivedUnitFacade derivedUnitFacade = DerivedUnitFacade.NewInstance(type);
1297
        derivedUnitFacade.setFieldUnit(state.getFieldUnit(state.getDataHolder().getFieldNumber()));
1298
        derivedUnitFacade.setDerivedUnitKindOfUnit(kindOfUnit);
1299
        derivedUnitFacade.setPreferredStableUri(state.getDataHolder().getPreferredStableUri());
1300
        // derivedUnitFacade.setDerivedUnitKindOfUnit(kindOfUnit);
1301
        return derivedUnitFacade;
1302
    }
1303

    
1304
    private void getCollectorsFromXML(Element root, Abcd206XMLFieldGetter abcdFieldGetter, Abcd206ImportState state) {
1305
        NodeList group;
1306

    
1307
        group = root.getChildNodes();
1308
        for (int i = 0; i < group.getLength(); i++) {
1309
            if (group.item(i).getNodeName().equals(state.getPrefix() + "Identifications")) {
1310
                group = group.item(i).getChildNodes();
1311
                break;
1312
            }
1313
        }
1314
        // state.getDataHolder().gatheringAgents = "";
1315

    
1316
        abcdFieldGetter.getType(root);
1317
        abcdFieldGetter.getGatheringPeople(root);
1318
    }
1319

    
1320

    
1321
    /**
1322
     * Load the list of names from the ABCD file and save them
1323
     *
1324
     * @param state
1325
     *            : the current ABCD import state
1326
     * @param unitsList
1327
     *            : the unit list from the ABCD file
1328
     * @param abcdFieldGetter
1329
     *            : the ABCD parser
1330
     */
1331
    private void prepareCollectors(Abcd206ImportState state, NodeList unitsList,
1332
            Abcd206XMLFieldGetter abcdFieldGetter) {
1333

    
1334
        TeamOrPersonBase<?> teamOrPerson = null;
1335
        Team team = null;
1336
        // ImportHelper.setOriginalSource(teamOrPerson,
1337
        // state.getConfig().getSourceReference(), collector, "Collector");
1338
        for (int i = 0; i < unitsList.getLength(); i++) {
1339
            this.getCollectorsFromXML((Element) unitsList.item(i), abcdFieldGetter, state);
1340
            if (!(state.getDataHolder().gatheringAgentsList.isEmpty())) {
1341
                if (state.getDataHolder().gatheringAgentsList.size() == 1) {
1342
                    teamOrPerson = parseAuthorString(state.getDataHolder().gatheringAgentsList.get(0));
1343
                } else {
1344
                    team = new Team();
1345
                    for (String collector : state.getDataHolder().gatheringAgentsList) {
1346
                        teamOrPerson = parseAuthorString(collector);
1347
                        if (teamOrPerson instanceof Person) {
1348
                            team.addTeamMember((Person) teamOrPerson);
1349
                        } else {
1350
                            for (Person person : ((Team) teamOrPerson).getTeamMembers()) {
1351
                                team.addTeamMember(person);
1352
                            }
1353
                        }
1354
                    }
1355
                    if (team.getTeamMembers() != null && team.getTeamMembers().isEmpty()){
1356
                        teamOrPerson = team;
1357
                    }
1358
                }
1359
                if (!state.getPersonStore().containsId(teamOrPerson.getTitleCache())) {
1360
                    state.getPersonStore().put(teamOrPerson.getTitleCache(), teamOrPerson);
1361
                    if (logger.isDebugEnabled()) {
1362
                        logger.debug("Stored author " + state.getDataHolder().gatheringAgentsList.toString());
1363
                    }
1364
                    logger.warn("Not imported author with duplicated aut_id "
1365
                            + state.getDataHolder().gatheringAgentsList.toString());
1366
                }
1367
            }
1368
            if (!StringUtils.isBlank(state.getDataHolder().gatheringAgentsText)
1369
                    && state.getDataHolder().gatheringAgentsList.isEmpty()) {
1370
                teamOrPerson = parseAuthorString(state.getDataHolder().gatheringAgentsText);
1371
                // if (teamOrPerson instanceof Person) {
1372
                // //team.addTeamMember((Person) teamOrPerson);
1373
                // } else {
1374
                // team = new Team();
1375
                // for (Person person : ((Team) teamOrPerson).getTeamMembers())
1376
                // {
1377
                // team.addTeamMember(person);
1378
                // }
1379
                // }
1380
                if (!state.getPersonStore().containsId(teamOrPerson.getTitleCache())) {
1381
                    state.getPersonStore().put(teamOrPerson.getTitleCache(), teamOrPerson);
1382
                    if (logger.isDebugEnabled()) {
1383
                        logger.debug("Stored author " + state.getDataHolder().gatheringAgentsText);
1384
                    }
1385
                    logger.warn("Not imported author with duplicated aut_id "
1386
                            + state.getDataHolder().gatheringAgentsList.toString());
1387
                }
1388
            }
1389

    
1390
        }
1391

    
1392
        // List<String> collectorsU = new ArrayList<String>(new
1393
        // HashSet<String>(collectors));
1394
        // List<String> teamsU = new ArrayList<String>(new
1395
        // HashSet<String>(teams));
1396
        //
1397
        //
1398
        // //existing teams in DB
1399
        // Map<String,Team> titleCacheTeam = new HashMap<String, Team>();
1400
        // List<UuidAndTitleCache<Team>> hiberTeam = new
1401
        // ArrayList<UuidAndTitleCache<Team>>();//getAgentService().getTeamUuidAndTitleCache();
1402

    
1403
        // Set<UUID> uuids = new HashSet<UUID>();
1404
        // for (UuidAndTitleCache<Team> hibernateT:hiberTeam){
1405
        // uuids.add(hibernateT.getUuid());
1406
        // }
1407
        // if (!uuids.isEmpty()){
1408
        // List<AgentBase> existingTeams = getAgentService().find(uuids);
1409
        // for (AgentBase<?> existingP:existingTeams){
1410
        // titleCacheTeam.put(existingP.getTitleCache(),CdmBase.deproxy(existingP,Team.class));
1411
        // }
1412
        // }
1413

    
1414
        // Map<String,UUID> teamMap = new HashMap<String, UUID>();
1415
        // for (UuidAndTitleCache<Team> uuidt:hiberTeam){
1416
        // teamMap.put(uuidt.getTitleCache(), uuidt.getUuid());
1417
        // }
1418

    
1419
        // existing persons in DB
1420
        // List<UuidAndTitleCache<Person>> hiberPersons = new
1421
        // ArrayList<UuidAndTitleCache<Person>>();//getAgentService().getPersonUuidAndTitleCache();
1422
        // Map<String,Person> titleCachePerson = new HashMap<String, Person>();
1423
        // uuids = new HashSet<UUID>();
1424
        // for (UuidAndTitleCache<Person> hibernateP:hiberPersons){
1425
        // uuids.add(hibernateP.getUuid());
1426
        // }
1427
        //
1428
        // if (!uuids.isEmpty()){
1429
        // List<AgentBase> existingPersons = getAgentService().find(uuids);
1430
        // for (AgentBase<?> existingP:existingPersons){
1431
        // titleCachePerson.put(existingP.getTitleCache(),CdmBase.deproxy(existingP,Person.class));
1432
        // }
1433
        // }
1434
        //
1435
        // Map<String,UUID> personMap = new HashMap<String, UUID>();
1436
        // for (UuidAndTitleCache<Person> person:hiberPersons){
1437
        // personMap.put(person.getTitleCache(), person.getUuid());
1438
        // }
1439
        //
1440
        // java.util.Collection<Person> personToadd = new ArrayList<Person>();
1441
        // java.util.Collection<Team> teamToAdd = new ArrayList<Team>();
1442
        //
1443
        // for (String collector:collectorsU){
1444
        // Person p = Person.NewInstance();
1445
        // p.setTitleCache(collector,true);
1446
        // if (!personMap.containsKey(p.getTitleCache())){
1447
        // personToadd.add(p);
1448
        // }
1449
        // }
1450
        // for (String team:teamsU){
1451
        // Team p = Team.NewInstance();
1452
        // p.setTitleCache(team,true);
1453
        // if (!teamMap.containsKey(p.getTitleCache())){
1454
        // teamToAdd.add(p);
1455
        // }
1456
        // }
1457
        //
1458
        // if(!personToadd.isEmpty()){
1459
        // for (Person agent: personToadd){
1460
        // save(agent, state);
1461
        // titleCachePerson.put(agent.getTitleCache(),CdmBase.deproxy(agent,
1462
        // Person.class) );
1463
        // }
1464
        // }
1465
        //
1466
        // Person ptmp ;
1467
        // Map <String,Integer>teamdone = new HashMap<String, Integer>();
1468
        // for (List<String> collteam: collectorinteams){
1469
        // if (!teamdone.containsKey(StringUtils.join(collteam.toArray(),"-"))){
1470
        // Team team = new Team();
1471
        // boolean em =true;
1472
        // for (String collector:collteam){
1473
        // ptmp = Person.NewInstance();
1474
        // ptmp.setTitleCache(collector,true);
1475
        // Person p2 = titleCachePerson.get(ptmp.getTitleCache());
1476
        // team.addTeamMember(p2);
1477
        // em=false;
1478
        // }
1479
        // if (!em) {
1480
        // teamToAdd.add(team);
1481
        // }
1482
        // teamdone.put(StringUtils.join(collteam.toArray(),"-"),0);
1483
        // }
1484
        // }
1485
        //
1486
        // if(!teamToAdd.isEmpty()){
1487
        // for (Team agent: teamToAdd){
1488
        // save(agent, state);
1489
        // titleCacheTeam.put(agent.getTitleCache(), CdmBase.deproxy(
1490
        // agent,Team.class) );
1491
        // }
1492
        // }
1493

    
1494
        // ((Abcd206ImportConfigurator)
1495
        // state.getConfig()).setTeams(titleCacheTeam);
1496
        // ((Abcd206ImportConfigurator)
1497
        // state.getConfig()).setPersons(titleCachePerson);
1498
    }
1499

    
1500
    @Override
1501
    protected boolean doCheck(Abcd206ImportState state) {
1502
        logger.warn("Checking not yet implemented for " + this.getClass().getSimpleName());
1503
        return true;
1504
    }
1505

    
1506
    @Override
1507
    protected boolean isIgnore(Abcd206ImportState state) {
1508
        return false;
1509
    }
1510

    
1511
    @Override
1512
    protected DefinedTerm getKindOfUnit(Abcd206ImportState state, UUID uuid, String label, String description,
1513
            String labelAbbrev, TermVocabulary<DefinedTerm> voc) {
1514

    
1515
        DefinedTerm unit = null;
1516

    
1517
        if (uuid == null) {
1518
            unit = this.kindOfUnitsMap.get(label.toLowerCase());
1519
        } else {
1520
            unit = state.getKindOfUnit(uuid);
1521

    
1522
        }
1523
        if (unit == null) {
1524
            unit = (DefinedTerm) getTermService().find(uuid);
1525
            if (unit == null) {
1526
                if (uuid == null) {
1527
                    uuid = UUID.randomUUID();
1528
                }
1529
                unit = DefinedTerm.NewKindOfUnitInstance(description, label, labelAbbrev);
1530
                unit.setUuid(uuid);
1531
                if (voc == null) {
1532
                    boolean isOrdered = false;
1533
                    voc = getVocabulary(state, TermType.KindOfUnit, uuidUserDefinedKindOfUnitVocabulary,
1534
                            "User defined vocabulary for kind-of-units", "User Defined Measurement kind-of-units", null,
1535
                            null, isOrdered, unit);
1536
                }
1537
                voc.addTerm(unit);
1538
                getTermService().save(unit);
1539
            }
1540
            state.putKindOfUnit(unit);
1541
            kindOfUnitsMap.put(unit.getLabel().toLowerCase(), unit);
1542
        }
1543
        return unit;
1544
    }
1545

    
1546

    
1547

    
1548
}
(2-2/15)