Project

General

Profile

Download (85.8 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.InputStream;
13
import java.net.MalformedURLException;
14
import java.net.URI;
15
import java.util.ArrayList;
16
import java.util.HashMap;
17
import java.util.HashSet;
18
import java.util.List;
19
import java.util.Map;
20
import java.util.Set;
21
import java.util.UUID;
22

    
23
import javax.xml.parsers.DocumentBuilder;
24
import javax.xml.parsers.DocumentBuilderFactory;
25

    
26
import org.apache.commons.lang.StringUtils;
27
import org.apache.log4j.Logger;
28
import org.springframework.stereotype.Component;
29
import org.w3c.dom.Document;
30
import org.w3c.dom.Element;
31
import org.w3c.dom.NodeList;
32

    
33
import eu.etaxonomy.cdm.api.application.ICdmApplicationConfiguration;
34
import eu.etaxonomy.cdm.api.facade.DerivedUnitFacade;
35
import eu.etaxonomy.cdm.common.UriUtils;
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.model.agent.AgentBase;
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.common.CdmBase;
45
import eu.etaxonomy.cdm.model.common.DefinedTermBase;
46
import eu.etaxonomy.cdm.model.common.IdentifiableSource;
47
import eu.etaxonomy.cdm.model.common.Language;
48
import eu.etaxonomy.cdm.model.common.LanguageString;
49
import eu.etaxonomy.cdm.model.common.OriginalSourceBase;
50
import eu.etaxonomy.cdm.model.common.OriginalSourceType;
51
import eu.etaxonomy.cdm.model.common.UuidAndTitleCache;
52
import eu.etaxonomy.cdm.model.description.DescriptionBase;
53
import eu.etaxonomy.cdm.model.description.DescriptionElementSource;
54
import eu.etaxonomy.cdm.model.description.Feature;
55
import eu.etaxonomy.cdm.model.description.IndividualsAssociation;
56
import eu.etaxonomy.cdm.model.description.TaxonDescription;
57
import eu.etaxonomy.cdm.model.location.NamedArea;
58
import eu.etaxonomy.cdm.model.media.Media;
59
import eu.etaxonomy.cdm.model.name.BacterialName;
60
import eu.etaxonomy.cdm.model.name.BotanicalName;
61
import eu.etaxonomy.cdm.model.name.CultivarPlantName;
62
import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
63
import eu.etaxonomy.cdm.model.name.NonViralName;
64
import eu.etaxonomy.cdm.model.name.Rank;
65
import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;
66
import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignationStatus;
67
import eu.etaxonomy.cdm.model.name.TaxonNameBase;
68
import eu.etaxonomy.cdm.model.name.ZoologicalName;
69
import eu.etaxonomy.cdm.model.occurrence.Collection;
70
import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
71
import eu.etaxonomy.cdm.model.occurrence.DeterminationEvent;
72
import eu.etaxonomy.cdm.model.occurrence.GatheringEvent;
73
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
74
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationType;
75
import eu.etaxonomy.cdm.model.reference.Reference;
76
import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
77
import eu.etaxonomy.cdm.model.taxon.Classification;
78
import eu.etaxonomy.cdm.model.taxon.Taxon;
79
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
80
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
81
import eu.etaxonomy.cdm.persistence.query.MatchMode;
82
import eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl;
83

    
84
/**
85
 * @author p.kelbert
86
 * @created 20.10.2008
87
 */
88
@Component
89
public class Abcd206Import extends SpecimenImportBase<Abcd206ImportConfigurator, Abcd206ImportState> {
90
    private static final Logger logger = Logger.getLogger(Abcd206Import.class);
91

    
92

    
93
    private final boolean DEBUG = true;
94

    
95
    private static final String PREFERRED = "_preferred_";
96
    private static final String CODE = "_code_";
97
    private static final String COLON = ":";
98
    private static final String SPLITTER = "--";
99

    
100

    
101

    
102

    
103

    
104
    private static String prefix = "";
105

    
106
    //TODO make all fields ABCD206ImportState variables
107
    private Classification classification = null;
108
    private Reference<?> ref = null;
109

    
110
    private Abcd206DataHolder dataHolder;
111
    private DerivedUnit derivedUnitBase;
112

    
113
    private List<OriginalSourceBase<?>> associationRefs = new ArrayList<OriginalSourceBase<?>>();
114
    boolean associationSourcesSet=false;
115
    private List<OriginalSourceBase<?>> descriptionRefs = new ArrayList<OriginalSourceBase<?>>();
116
    boolean descriptionSourcesSet=false;
117
    private List<OriginalSourceBase<?>> derivedUnitSources = new ArrayList<OriginalSourceBase<?>>();
118
    boolean derivedUnitSourcesSet=false;
119
    private boolean descriptionGroupSet = false;
120
    private TaxonDescription descriptionGroup = null;
121

    
122
    public Abcd206Import() {
123
        super();
124
    }
125

    
126
    @Override
127
    protected boolean doCheck(Abcd206ImportState state) {
128
        logger.warn("Checking not yet implemented for " + this.getClass().getSimpleName());
129
        return true;
130
    }
131

    
132

    
133
    @Override
134
    @SuppressWarnings("rawtypes")
135
    public void doInvoke(Abcd206ImportState state) {
136
        state.setTx(startTransaction());
137
        logger.info("INVOKE Specimen Import from ABCD2.06 XML ");
138

    
139
        SpecimenUserInteraction sui = state.getConfig().getSpecimenUserInteraction();
140

    
141
        List<Reference> references = getReferenceService().list(Reference.class, null, null, null, null);
142

    
143
        if (state.getConfig().isInteractWithUser()){
144
            Map<String,Reference> refMap = new HashMap<String, Reference>();
145
            for (Reference tree : references) {
146
                if (! StringUtils.isBlank(tree.getTitleCache())) {
147
                    refMap.put(tree.getTitleCache(),tree);
148
                }
149
            }
150
            ref = sui.askForReference(refMap);
151

    
152
            if (ref == null){
153
                String cla = sui.createNewReference();
154
                if (refMap.get(cla)!= null) {
155
                    ref = refMap.get(cla);
156
                } else {
157
                    ref = ReferenceFactory.newGeneric();
158
                    ref.setTitle(cla);
159
                }
160
            }
161
            else{
162
                ref = getReferenceService().find(ref.getUuid());
163
            }
164
        }else{
165
            if (ref==null){
166
                String name = NB(state.getConfig().getSourceReferenceTitle());
167
                for (Reference tree : references) {
168
                    if (! StringUtils.isBlank(tree.getTitleCache())) {
169
                        if (tree.getTitleCache().equalsIgnoreCase(name)) {
170
                            ref=tree;
171
//                            System.out.println("FIND SAME REFERENCE");
172
                        }
173
                    }
174
                }
175
                if (ref == null){
176
                    ref = ReferenceFactory.newGeneric();
177
                    ref.setTitle("ABCD classic");
178
                }
179
            }
180
        }
181
        save(ref, state);
182
        state.getConfig().setSourceReference(ref);
183

    
184
        List<Classification> classificationList = getClassificationService().list(Classification.class, null, null, null, null);
185
        if (state.getConfig().isUseClassification() && state.getConfig().isInteractWithUser()){
186
            Map<String,Classification> classMap = new HashMap<String, Classification>();
187
            for (Classification tree : classificationList) {
188
                if (! StringUtils.isBlank(tree.getTitleCache())) {
189
                    classMap.put(tree.getTitleCache(),tree);
190
                }
191
            }
192
            classification = sui.askForClassification(classMap);
193
            if (classification == null){
194
                String cla = sui.createNewClassification();
195
                if (classMap.get(cla)!= null) {
196
                    classification = classMap.get(cla);
197
                } else {
198
                    classification = Classification.NewInstance(cla, ref, Language.DEFAULT());
199
                }
200
            }
201
            save(classification, state);
202
        }
203
        else{
204
            if (classification == null) {
205
                String name = NB(state.getConfig().getClassificationName());
206
                for (Classification classif : classificationList){
207
                    if (classif.getTitleCache().equalsIgnoreCase(name) && classif.getCitation().equals(ref)) {
208
                        classification=classif;
209
//                        System.out.println("FIND SAME CLASSIF");
210
                    }
211
                }
212
                if (classification == null){
213
                    classification = Classification.NewInstance(name, ref, Language.DEFAULT());
214
                }
215
                //                if (state.getConfig().getClassificationUuid() != null) {
216
                //                    classification.setUuid(state.getConfig().getClassificationUuid());
217
                //                }
218
                save(classification, state);
219
            }
220
        }
221

    
222
        InputStream source = state.getConfig().getSource();
223
        NodeList unitsList = getUnitsNodeList(source);
224

    
225
        if (unitsList != null) {
226
            String message = "nb units to insert: " + unitsList.getLength();
227
            logger.info(message);
228
            updateProgress(state, message);
229

    
230
            dataHolder = new Abcd206DataHolder();
231

    
232
            Abcd206XMLFieldGetter abcdFieldGetter = new Abcd206XMLFieldGetter(dataHolder, prefix);
233

    
234
            prepareCollectors(state, unitsList, abcdFieldGetter);
235

    
236
            associationRefs = new ArrayList<OriginalSourceBase<?>>();
237
            descriptionRefs = new ArrayList<OriginalSourceBase<?>>();
238
            derivedUnitSources = new ArrayList<OriginalSourceBase<?>>();
239

    
240
            for (int i = 0; i < unitsList.getLength(); i++) {
241
                System.out.println("------------------------------------------------------------------------------------------");
242

    
243
                this.setUnitPropertiesXML( (Element) unitsList.item(i), abcdFieldGetter);
244
                //				refreshTransaction(state);
245
                this.handleSingleUnit(state);
246

    
247
                // compare the ABCD elements added in to the CDM and the
248
                // unhandled ABCD elements
249
                //compareABCDtoCDM(sourceName, dataHolder.knownABCDelements, abcdFieldGetter);
250

    
251
                // reset the ABCD elements added in CDM
252
                // knownABCDelements = new ArrayList<String>();
253
                dataHolder.allABCDelements = new HashMap<String, String>();
254
            }
255
            getReferenceService().deduplicate(Reference.class, null, null);
256
            getClassificationService().deduplicate(Classification.class, null, null);
257
        }
258
        commitTransaction(state.getTx());
259
        return;
260

    
261
    }
262

    
263

    
264
    protected NodeList getUnitsNodeList(URI source) {
265
        try {
266
            InputStream is = UriUtils.getInputStream(source);
267
            return getUnitsNodeList(is);
268
        } catch (Exception e) {
269
            logger.warn(e);
270
            throw new RuntimeException(e);
271
        }
272
    }
273

    
274
    /**
275
     * Return the list of root nodes for an ABCD 2.06 XML file
276
     * @param fileName: the file's location
277
     * @return the list of root nodes ("Unit")
278
     */
279
    protected NodeList getUnitsNodeList(InputStream inputStream) {
280
        NodeList unitList = null;
281
        try {
282
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
283
            DocumentBuilder builder = factory.newDocumentBuilder();
284

    
285
            Document document = builder.parse(inputStream);
286
            Element root = document.getDocumentElement();
287
            unitList = root.getElementsByTagName("Unit");
288
            if (unitList.getLength() == 0) {
289
                unitList = root.getElementsByTagName("abcd:Unit");
290
                prefix = "abcd:";
291
            }
292
        } catch (Exception e) {
293
            logger.warn(e);
294
        }
295
        return unitList;
296
    }
297

    
298
    /**
299
     * Handle a single unit
300
     * @param state
301
     */
302
    @SuppressWarnings("rawtypes")
303
    private void handleSingleUnit(Abcd206ImportState state) {
304
        if (DEBUG) {
305
            logger.info("handleSingleUnit "+ref);
306
        }
307
        try {
308
            updateProgress(state, "Importing data for unit: " + dataHolder.unitID);
309

    
310
            // create facade
311
            DerivedUnitFacade derivedUnitFacade = getFacade();
312
            derivedUnitBase = derivedUnitFacade.innerDerivedUnit();
313

    
314
            /**
315
             * GATHERING EVENT
316
             */
317
            // gathering event
318
            UnitsGatheringEvent unitsGatheringEvent = new UnitsGatheringEvent(getTermService(), dataHolder.locality, dataHolder.languageIso,
319
                    dataHolder.longitude, dataHolder.latitude, dataHolder.gatheringAgentList, dataHolder.gatheringTeamList,state.getConfig());
320

    
321
            // country
322
            UnitsGatheringArea unitsGatheringArea = new UnitsGatheringArea();
323
            //  unitsGatheringArea.setConfig(state.getConfig(),getOccurrenceService(), getTermService());
324
            unitsGatheringArea.setParams(dataHolder.isocountry, dataHolder.country, state.getConfig(), getTermService(), getOccurrenceService());
325

    
326
            DefinedTermBase<?> areaCountry =  unitsGatheringArea.getCountry();
327

    
328
            // other areas
329
            unitsGatheringArea = new UnitsGatheringArea();
330
            //            unitsGatheringArea.setConfig(state.getConfig(),getOccurrenceService(),getTermService());
331
            unitsGatheringArea.setAreas(dataHolder.namedAreaList,state.getConfig(), getTermService());
332
            ArrayList<DefinedTermBase> nas = unitsGatheringArea.getAreas();
333
            for (DefinedTermBase namedArea : nas) {
334
                unitsGatheringEvent.addArea(namedArea);
335
            }
336

    
337
            // copy gathering event to facade
338
            GatheringEvent gatheringEvent = unitsGatheringEvent.getGatheringEvent();
339
            derivedUnitFacade.setLocality(gatheringEvent.getLocality());
340
            derivedUnitFacade.setExactLocation(gatheringEvent.getExactLocation());
341
            derivedUnitFacade.setCollector(gatheringEvent.getCollector());
342
            derivedUnitFacade.setCountry((NamedArea)areaCountry);
343

    
344
            for(DefinedTermBase<?> area:unitsGatheringArea.getAreas()){
345
                derivedUnitFacade.addCollectingArea((NamedArea) area);
346
            }
347
            //            derivedUnitFacade.addCollectingAreas(unitsGatheringArea.getAreas());
348
            // TODO exsiccatum
349

    
350
            // add fieldNumber
351
            derivedUnitFacade.setFieldNumber(NB(dataHolder.fieldNumber));
352

    
353
            // //add Multimedia URLs
354
            if (dataHolder.multimediaObjects.size() != -1) {
355
                for (String multimediaObject : dataHolder.multimediaObjects) {
356
                    Media media;
357
                    try {
358
                        media = getImageMedia(multimediaObject, READ_MEDIA_DATA);
359
                        derivedUnitFacade.addDerivedUnitMedia(media);
360
                    } catch (MalformedURLException e) {
361
                        // TODO Auto-generated catch block
362
                        e.printStackTrace();
363
                    }
364

    
365
                }
366
            }
367

    
368
            //			/*
369
            //			 * merge AND STORE DATA
370
            //			 */
371
            //			getTermService().saveOrUpdate(areaCountry);// TODO save area sooner
372
            //
373
            //			for (NamedArea area : otherAreas) {
374
            //				getTermService().saveOrUpdate(area);// merge it sooner (foreach area)
375
            //			}
376

    
377
            save(unitsGatheringEvent.getLocality(), state);
378

    
379
            // handle collection data
380
            setCollectionData(state, derivedUnitFacade);
381

    
382
            //Reference stuff
383
            SpecimenUserInteraction sui = state.getConfig().getSpecimenUserInteraction();
384
            Map<String,OriginalSourceBase<?>> sourceMap = new HashMap<String, OriginalSourceBase<?>>();
385

    
386
            dataHolder.docSources = new ArrayList<String>();
387
            for (String[] fullReference : dataHolder.referenceList) {
388
                String strReference=fullReference[0];
389
                String citationDetail = fullReference[1];
390
                String citationURL = fullReference[2];
391

    
392
                if (!citationURL.isEmpty()) {
393
                    citationDetail+=", "+citationURL;
394
                }
395

    
396
                Reference<?> reference = ReferenceFactory.newGeneric();
397
                reference.setTitleCache(strReference);
398

    
399
                IdentifiableSource sour = getIdentifiableSource(reference,citationDetail);
400

    
401
                try{
402
                    if (sour.getCitation() != null){
403
                        if(StringUtils.isNotBlank(sour.getCitationMicroReference())) {
404
                            dataHolder.docSources.add(sour.getCitation().getTitleCache()+ "---"+sour.getCitationMicroReference());
405
                        } else {
406
                            dataHolder.docSources.add(sour.getCitation().getTitleCache());
407
                        }
408
                    }
409
                }catch(Exception e){
410
                    logger.warn("oups");
411
                }
412
                reference.addSource(sour);
413
                save(reference, state);
414
            }
415

    
416

    
417
            List<IdentifiableSource> issTmp = getCommonService().list(IdentifiableSource.class, null, null, null, null);
418
            List<DescriptionElementSource> issTmp2 = getCommonService().list(DescriptionElementSource.class, null, null, null, null);
419

    
420
            Set<OriginalSourceBase> osbSet = new HashSet<OriginalSourceBase>();
421
            if(issTmp2!=null) {
422
                osbSet.addAll(issTmp2);
423
            }
424
            if(issTmp!=null) {
425
                osbSet.addAll(issTmp);
426
            }
427

    
428

    
429
            for( OriginalSourceBase<?> osb:osbSet) {
430
                if(osb.getCitationMicroReference() !=null  && !osb.getCitationMicroReference().isEmpty()) {
431
                    try{
432
                        sourceMap.put(osb.getCitation().getTitleCache()+ "---"+osb.getCitationMicroReference(),osb);
433
                    }catch(NullPointerException e){logger.warn("null pointer problem (no ref?) with "+osb);}
434
                } else{
435
                    try{
436
                        sourceMap.put(osb.getCitation().getTitleCache(),osb);
437
                    }catch(NullPointerException e){logger.warn("null pointer problem (no ref?) with "+osb);}
438
                }
439
            }
440

    
441
            if( state.getConfig().isInteractWithUser()){
442
                List<OriginalSourceBase<?>>sources=null;
443
                if(!derivedUnitSourcesSet){
444
                    sources= sui.askForSource(sourceMap, "the unit itself","",getReferenceService(), dataHolder.docSources);
445
                    derivedUnitSources=sources;
446
                    derivedUnitSourcesSet=true;
447
                }
448
                else{
449
                    sources=derivedUnitSources;
450
                }
451
//                System.out.println("nb sources: "+sources.size());
452
//                System.out.println("derivedunitfacade : "+derivedUnitFacade.getTitleCache());
453
                for (OriginalSourceBase<?> sour:sources){
454
                    if(sour.isInstanceOf(IdentifiableSource.class)){
455
                        if(sourceNotLinkedToElement(derivedUnitFacade,sour)) {
456
//                            System.out.println("add source to derivedunitfacade1 "+derivedUnitFacade.getTitleCache());
457
                            derivedUnitFacade.addSource((IdentifiableSource)sour.clone());
458
                        }
459
                    }else{
460
                        if(sourceNotLinkedToElement(derivedUnitFacade,sour)) {
461
//                            System.out.println("add source to derivedunitfacade2 "+derivedUnitFacade.getTitleCache());
462
                            derivedUnitFacade.addSource(OriginalSourceType.Import,sour.getCitation(),sour.getCitationMicroReference(), ioName);
463
                        }
464
                    }
465
                }
466
            }else{
467
                for (OriginalSourceBase<?> sr : sourceMap.values()){
468
                    if(sr.isInstanceOf(IdentifiableSource.class)){
469
                        if(sourceNotLinkedToElement(derivedUnitFacade,sr)) {
470
//                            System.out.println("add source to derivedunitfacade3 "+derivedUnitFacade.getTitleCache());
471
                            derivedUnitFacade.addSource((IdentifiableSource)sr.clone());
472
                        }
473
                    }else{
474
                        if(sourceNotLinkedToElement(derivedUnitFacade,sr)) {
475
//                            System.out.println("add source to derivedunitfacade4 "+derivedUnitFacade.getTitleCache());
476
                            derivedUnitFacade.addSource(OriginalSourceType.Import,sr.getCitation(),sr.getCitationMicroReference(), ioName);
477
                        }
478
                    }
479
                }
480
            }
481

    
482
            save(derivedUnitBase, state);
483

    
484
            // handle identifications
485
            handleIdentifications(state, derivedUnitFacade);
486

    
487
            if(DEBUG) {
488
                logger.info("saved ABCD specimen ...");
489
            }
490

    
491
        } catch (Exception e) {
492
            logger.warn("Error when reading record!!");
493
            e.printStackTrace();
494
            state.setUnsuccessfull();
495
        }
496

    
497
        return;
498
    }
499

    
500
    /**
501
     * @param derivedUnitFacade
502
     * @param sour
503
     * @return
504
     */
505
    private boolean sourceNotLinkedToElement(DerivedUnitFacade derivedUnitFacade, OriginalSourceBase<?> source) {
506
        Set<IdentifiableSource> linkedSources = derivedUnitFacade.getSources();
507
        for (IdentifiableSource is:linkedSources){
508
            if (is.getCitation()!=null && source.getCitation()!=null &&
509
                    is.getCitation().getTitleCache().equalsIgnoreCase(source.getCitation().getTitleCache())){
510
                String isDetail =  is.getCitationMicroReference();
511
                if ((StringUtils.isBlank(isDetail) && StringUtils.isBlank(source.getCitationMicroReference()))
512
                        || (isDetail != null && isDetail.equalsIgnoreCase(source.getCitationMicroReference())) ) {
513
                    return false;
514
                }
515
            }
516
        }
517
        return true;
518
    }
519

    
520
    /**
521
     * @param reference
522
     * @param citationDetail
523
     * @return
524
     */
525
    //FIXME this method is highly critical, because
526
    //  * it will have serious performance and memory problems with large databases
527
    //        (databases may easily have >1 Mio source records)
528
    //  * it does not make sense to search for existing sources and then clone them
529
    //    we need to search for existing references instead and use them (if exist)
530
    //    for our new source.
531
    private IdentifiableSource getIdentifiableSource(Reference<?> reference, String citationDetail) {
532

    
533
        List<IdentifiableSource> issTmp = getCommonService().list(IdentifiableSource.class, null, null, null, null);
534

    
535

    
536
        if (reference != null){
537
            try {
538
                for (OriginalSourceBase<?> osb: issTmp){
539
                    if (osb.getCitation() != null && reference!=null && osb.getCitation().getTitleCache().equalsIgnoreCase(reference.getTitleCache())){
540
                        String osbDetail = osb.getCitationMicroReference();
541
                        if ((StringUtils.isBlank(osbDetail) && StringUtils.isBlank(citationDetail))
542
                                || (osbDetail != null && osbDetail.equalsIgnoreCase(citationDetail)) ) {
543
//                            System.out.println("REFERENCE FOUND RETURN EXISTING SOURCE");
544
                            return (IdentifiableSource) osb.clone();
545
                        }
546
                    }
547
                }
548
            } catch (CloneNotSupportedException e) {
549
                throw new RuntimeException(e);
550
            } catch (Exception e1){
551
                e1.printStackTrace();
552
            }
553
        }
554

    
555
        IdentifiableSource sour = IdentifiableSource.NewInstance(OriginalSourceType.Import,null,null, reference,citationDetail);
556
        return sour;
557
    }
558

    
559
    //    /**
560
    //     * @param reference
561
    //     * @param citationDetail
562
    //     * @return
563
    //     */
564
    //    private DescriptionElementSource getDescriptionSource(Reference<?> reference, String citationDetail) {
565
    //
566
    //        List<OriginalSourceBase> issTmp2 = getCommonService().list(DescriptionElementSource.class, null, null, null, null);
567
    //
568
    //        try {
569
    //            for (OriginalSourceBase<?> osb:issTmp2){
570
    //                if (osb.getCitation().equals(reference) && osb.getCitationMicroReference().equalsIgnoreCase(citationDetail)) {
571
    //                    return (DescriptionElementSource) osb.clone();
572
    //                }
573
    //            }
574
    //        } catch (CloneNotSupportedException e) {
575
    //            // TODO Auto-generated catch block
576
    //            e.printStackTrace();
577
    //        }
578
    //
579
    //        DescriptionElementSource sour = DescriptionElementSource.NewInstance(OriginalSourceType.Import,null,null, reference,citationDetail);
580
    //        return sour;
581
    //    }
582

    
583

    
584
    /**
585
     * Very fast and dirty implementation to allow handling of transient objects as described in
586
     * https://dev.e-taxonomy.eu/trac/ticket/3726
587
     *
588
     * Not yet complete.
589
     *
590
     * @param cdmBase
591
     * @param state
592
     */
593
    private void save(CdmBase cdmBase, Abcd206ImportState state) {
594
        ICdmApplicationConfiguration cdmRepository = state.getConfig().getCdmAppController();
595
        if (cdmRepository == null){
596
            cdmRepository = this;
597
        }
598

    
599
        if (cdmBase.isInstanceOf(LanguageString.class)){
600
            cdmRepository.getTermService().saveLanguageData(CdmBase.deproxy(cdmBase, LanguageString.class));
601
        }else if (cdmBase.isInstanceOf(SpecimenOrObservationBase.class)){
602
            cdmRepository.getOccurrenceService().saveOrUpdate(CdmBase.deproxy(cdmBase, SpecimenOrObservationBase.class));
603
        }else if (cdmBase.isInstanceOf(Reference.class)){
604
            cdmRepository.getReferenceService().saveOrUpdate(CdmBase.deproxy(cdmBase, Reference.class));
605
        }else if (cdmBase.isInstanceOf(Classification.class)){
606
            cdmRepository.getClassificationService().saveOrUpdate(CdmBase.deproxy(cdmBase, Classification.class));
607
        }else if (cdmBase.isInstanceOf(AgentBase.class)){
608
            cdmRepository.getAgentService().saveOrUpdate(CdmBase.deproxy(cdmBase, AgentBase.class));
609
        }else if (cdmBase.isInstanceOf(Collection.class)){
610
            cdmRepository.getCollectionService().saveOrUpdate(CdmBase.deproxy(cdmBase, Collection.class));
611
        }else if (cdmBase.isInstanceOf(DescriptionBase.class)){
612
            cdmRepository.getDescriptionService().saveOrUpdate(CdmBase.deproxy(cdmBase, DescriptionBase.class));
613
        }else if (cdmBase.isInstanceOf(TaxonBase.class)){
614
            cdmRepository.getTaxonService().saveOrUpdate(CdmBase.deproxy(cdmBase, TaxonBase.class));
615
        }else if (cdmBase.isInstanceOf(TaxonNameBase.class)){
616
            cdmRepository.getNameService().saveOrUpdate(CdmBase.deproxy(cdmBase, TaxonNameBase.class));
617
        }else{
618
            throw new IllegalArgumentException("Class not supported in save method: " + CdmBase.deproxy(cdmBase, CdmBase.class).getClass().getSimpleName());
619
        }
620

    
621
    }
622

    
623
    /**
624
     * setCollectionData : store the collection object into the
625
     * derivedUnitFacade
626
     *
627
     * @param state
628
     */
629
    private void setCollectionData(Abcd206ImportState state, DerivedUnitFacade derivedUnitFacade) {
630
        // set catalogue number (unitID)
631
        derivedUnitFacade.setCatalogNumber(NB(dataHolder.unitID));
632
        derivedUnitFacade.setAccessionNumber(NB(dataHolder.accessionNumber));
633
        // derivedUnitFacade.setCollectorsNumber(NB(dataHolder.collectorsNumber));
634

    
635
        /*
636
         * INSTITUTION & COLLECTION
637
         */
638
        // manage institution
639
        Institution institution = this.getInstitution(NB(dataHolder.institutionCode), state);
640
        // manage collection
641
        Collection collection = this.getCollection(institution, NB(dataHolder.collectionCode), state);
642
        // link specimen & collection
643
        derivedUnitFacade.setCollection(collection);
644
    }
645

    
646
    /**
647
     * getFacade : get the DerivedUnitFacade based on the recordBasis
648
     *
649
     * @return DerivedUnitFacade
650
     */
651
    private DerivedUnitFacade getFacade() {
652
        if(DEBUG) {
653
            logger.info("getFacade()");
654
        }
655
        SpecimenOrObservationType type = null;
656

    
657
        // create specimen
658
        if (NB((dataHolder.recordBasis)) != null) {
659
            if (dataHolder.recordBasis.toLowerCase().startsWith("s") || dataHolder.recordBasis.toLowerCase().indexOf("specimen")>-1) {// specimen
660
                type = SpecimenOrObservationType.PreservedSpecimen;
661
            }
662
            if (dataHolder.recordBasis.toLowerCase().startsWith("o") ||dataHolder.recordBasis.toLowerCase().indexOf("observation")>-1 ) {
663
                type = SpecimenOrObservationType.Observation;
664
            }
665
            if (dataHolder.recordBasis.toLowerCase().indexOf("fossil")>-1){
666
                type = SpecimenOrObservationType.Fossil;
667
            }
668
            if (dataHolder.recordBasis.toLowerCase().indexOf("living")>-1) {
669
                type = SpecimenOrObservationType.LivingSpecimen;
670
            }
671
            if (type == null) {
672
                logger.info("The basis of record does not seem to be known: " + dataHolder.recordBasis);
673
                type = SpecimenOrObservationType.DerivedUnit;
674
            }
675
            // TODO fossils?
676
        } else {
677
            logger.info("The basis of record is null");
678
            type = SpecimenOrObservationType.DerivedUnit;
679
        }
680
        DerivedUnitFacade derivedUnitFacade = DerivedUnitFacade.NewInstance(type);
681
        return derivedUnitFacade;
682
    }
683

    
684
    private void getCollectorsFromXML(Element root, Abcd206XMLFieldGetter abcdFieldGetter) {
685
        NodeList group;
686

    
687
        group = root.getChildNodes();
688
        for (int i = 0; i < group.getLength(); i++) {
689
            if (group.item(i).getNodeName().equals(prefix + "Identifications")) {
690
                group = group.item(i).getChildNodes();
691
                break;
692
            }
693
        }
694
        dataHolder.gatheringAgentList = new ArrayList<String>();
695
        dataHolder.gatheringTeamList = new ArrayList<String>();
696
        abcdFieldGetter.getType(root);
697
        abcdFieldGetter.getGatheringPeople(root);
698
    }
699

    
700
    /**
701
     * Store the unit's properties into variables Look which unit is the
702
     * preferred one Look what kind of name it is supposed to be, for the
703
     * parsing (Botanical, Zoological)
704
     *
705
     * @param racine: the root node for a single unit
706
     */
707
    private void setUnitPropertiesXML(Element root, Abcd206XMLFieldGetter abcdFieldGetter) {
708
        try {
709
            NodeList group;
710

    
711
            group = root.getChildNodes();
712
            for (int i = 0; i < group.getLength(); i++) {
713
                if (group.item(i).getNodeName().equals(prefix + "Identifications")) {
714
                    group = group.item(i).getChildNodes();
715
                    break;
716
                }
717
            }
718
            dataHolder.identificationList = new ArrayList<String>();
719
            dataHolder.statusList = new ArrayList<SpecimenTypeDesignationStatus>();
720
            dataHolder.atomisedIdentificationList = new ArrayList<HashMap<String, String>>();
721
            dataHolder.referenceList = new ArrayList<String[]>();
722
            dataHolder.multimediaObjects = new ArrayList<String>();
723

    
724
            abcdFieldGetter.getScientificNames(group);
725
            abcdFieldGetter.getType(root);
726

    
727
            if(DEBUG) {
728
                logger.info("this.identificationList "+dataHolder.identificationList.toString());
729
            }
730
            abcdFieldGetter.getIDs(root);
731
            abcdFieldGetter.getRecordBasis(root);
732
            abcdFieldGetter.getMultimedia(root);
733
            abcdFieldGetter.getNumbers(root);
734
            abcdFieldGetter.getGeolocation(root);
735
            abcdFieldGetter.getGatheringPeople(root);
736
            boolean referencefound = abcdFieldGetter.getReferences(root);
737
            if (!referencefound) {
738
                String[]a = {ref.getTitleCache(),"",""};
739
                dataHolder.referenceList.add(a);
740
            }
741

    
742
        } catch (Exception e) {
743
            logger.info("Error occured while parsing XML file" + e);
744
        }
745
    }
746

    
747
    /**
748
     * Look if the Institution does already exist
749
     * @param institutionCode: a string with the institutioncode
750
     * @param config : the configurator
751
     * @return the Institution (existing or new)
752
     */
753
    @SuppressWarnings("rawtypes")
754
    private Institution getInstitution(String institutionCode, Abcd206ImportState state) {
755
        Institution institution=null;
756
        List<Institution> institutions;
757
        try {
758
            institutions = getAgentService().list(Institution.class, null, null, null, null);
759
        } catch (Exception e) {
760
            institutions = new ArrayList<Institution>();
761
            logger.warn(e);
762
        }
763
        if (institutions.size() > 0 && state.getConfig().isReUseExistingMetadata()) {
764
            for (Institution institut:institutions){
765
                try{
766
                    if (institut.getCode().equalsIgnoreCase(institutionCode)) {
767
                        institution=institut;
768
                    }
769
                }catch(Exception e){logger.warn("no institution code in the db");}
770
            }
771
        }
772
        if(DEBUG) {
773
            if(institution !=null) {
774
                logger.info("getinstitution " + institution.toString());
775
            }
776
        }
777
        if (institution == null){
778
            // create institution
779
            institution = Institution.NewInstance();
780
            institution.setCode(institutionCode);
781
            institution.setTitleCache(institutionCode, true);
782
        }
783
        save(institution, state);
784
        return institution;
785
    }
786

    
787
    /**
788
     * Look if the Collection does already exist
789
     * @param collectionCode
790
     * @param collectionCode: a string
791
     * @param config : the configurator
792
     * @return the Collection (existing or new)
793
     */
794
    private Collection getCollection(Institution institution, String collectionCode, Abcd206ImportState state) {
795
        Collection collection = null;
796
        List<Collection> collections;
797
        try {
798
            collections = getCollectionService().list(Collection.class, null, null, null, null);
799
        } catch (Exception e) {
800
            collections = new ArrayList<Collection>();
801
        }
802
        if (collections.size() > 0 && state.getConfig().isReUseExistingMetadata()) {
803
            for (Collection coll:collections){
804
                if (coll.getInstitute() != null) {
805
                    if (coll.getCode().equalsIgnoreCase(collectionCode) && coll.getInstitute().equals(institution)) {
806
                        collection=coll;
807
                    }
808
                }
809
            }
810
        }
811

    
812
        if(collection == null){
813
            collection =Collection.NewInstance();
814
            collection.setCode(collectionCode);
815
            collection.setInstitute(institution);
816
            collection.setTitleCache(collectionCode);
817
        }
818
        save(collection, state);
819
        return collection;
820
    }
821

    
822

    
823
    /**
824
     * join DeterminationEvent to the Taxon Object
825
     * @param state : the ABCD import state
826
     * @param taxon: the current Taxon
827
     * @param preferredFlag :if the current name is preferred
828
     * @param derivedFacade : the derived Unit Facade
829
     */
830
    @SuppressWarnings("rawtypes")
831
    private void linkDeterminationEvent(Abcd206ImportState state, Taxon taxon, boolean preferredFlag,  DerivedUnitFacade derivedFacade) {
832
        Abcd206ImportConfigurator config = state.getConfig();
833
        if(DEBUG){
834
            logger.info("start linkdetermination with taxon:" + taxon.getUuid()+", "+taxon);
835
        }
836

    
837
        DeterminationEvent determinationEvent = DeterminationEvent.NewInstance();
838
        determinationEvent.setTaxon(taxon);
839
        determinationEvent.setPreferredFlag(preferredFlag);
840

    
841
        determinationEvent.setIdentifiedUnit(derivedUnitBase);
842
        derivedUnitBase.addDetermination(determinationEvent);
843

    
844
        try {
845
            if(DEBUG){
846
                logger.info("NB TYPES INFO: "+ dataHolder.statusList.size());
847
            }
848
            for (SpecimenTypeDesignationStatus specimenTypeDesignationstatus : dataHolder.statusList) {
849
                if (specimenTypeDesignationstatus != null) {
850
                    if(DEBUG){
851
                        logger.info("specimenTypeDesignationstatus :"+ specimenTypeDesignationstatus);
852
                    }
853

    
854
                    specimenTypeDesignationstatus = (SpecimenTypeDesignationStatus) getTermService().find(specimenTypeDesignationstatus.getUuid());
855
                    //Designation
856
                    TaxonNameBase<?,?> name = taxon.getName();
857
                    SpecimenTypeDesignation designation = SpecimenTypeDesignation.NewInstance();
858

    
859
                    designation.setTypeStatus(specimenTypeDesignationstatus);
860
                    designation.setTypeSpecimen(derivedUnitBase);
861
                    name.addTypeDesignation(designation, true);
862
                }
863
            }
864
        } catch (Exception e) {
865
            logger.warn("PB addding SpecimenType " + e);
866
        }
867

    
868
        for (String[] fullReference : dataHolder.referenceList) {
869
            try{
870
//                System.out.println(fullReference);
871
                List<Reference> references = getReferenceService().list(Reference.class, null, null, null, null);
872

    
873
                String strReference=fullReference[0];
874
                String citationDetail = fullReference[1];
875
                String citationURL = fullReference[2];
876

    
877
                if (isNotBlank(strReference)){
878
                    Reference<?> reference = null;
879
                    for (Reference<?> refe: references) {
880
                        if (refe.getTitleCache().equalsIgnoreCase(strReference)) {
881
                            reference =refe;
882
                        }
883
                    }
884
                    if (reference ==null){
885
                        reference = ReferenceFactory.newGeneric();
886
                        /*<<<<<<< .courant
887
                    reference.setTitleCache(strReference);
888
                    System.out.println("reference hasproblem2 "+reference.hasProblem());
889
                    IdentifiableSource sour = IdentifiableSource.NewInstance(reference,citationDetail);
890
                    getReferenceService().saveOrUpdate(sour.getCitation());
891
=======*/
892
                        reference.setTitleCache(strReference, true);
893
                        save(reference, state);
894
                    }
895
                    determinationEvent.addReference(reference);
896
                }
897
            }catch(Exception e){logger.warn("pv getReferenceList "+e);}
898
        }
899
        save(derivedUnitBase, state);
900

    
901
        if (config.isAddIndividualsAssociationsSuchAsSpecimenAndObservations()) {
902
            if(DEBUG){
903
                logger.info("isDoCreateIndividualsAssociations");
904
            }
905

    
906
            makeIndividualsAssociation(state, taxon, determinationEvent);
907
            save(derivedUnitBase, state);
908
        }
909
    }
910

    
911
    /**
912
     * create and link each association (specimen, observation..) to the accepted taxon
913
     * @param state : the ABCD import state
914
     * @param taxon: the current Taxon
915
     * @param determinationEvent:the determinationevent
916
     */
917
    @SuppressWarnings("unused")
918
    private void makeIndividualsAssociation(Abcd206ImportState state, Taxon taxon, DeterminationEvent determinationEvent) {
919
        SpecimenUserInteraction sui = state.getConfig().getSpecimenUserInteraction();
920

    
921
        if (DEBUG) {
922
            System.out.println("MAKE INDIVIDUALS ASSOCIATION");
923
        }
924

    
925
        TaxonDescription taxonDescription = null;
926
        Set<TaxonDescription> descriptions= taxon.getDescriptions();
927
        if (state.getConfig().isInteractWithUser()){
928
            if(!descriptionGroupSet){
929
                taxonDescription = sui.askForDescriptionGroup(descriptions);
930
                descriptionGroup=taxonDescription;
931
                descriptionGroupSet=true;
932
            }else{
933
                taxonDescription=descriptionGroup;
934
            }
935
        } else {
936
            for (TaxonDescription description : descriptions){
937
                Set<IdentifiableSource> sources =  description.getTaxon().getSources();
938
                sources.addAll(description.getSources());
939
                for (IdentifiableSource source:sources){
940
                    if(ref.equals(source.getCitation())) {
941
                        taxonDescription = description;
942
                    }
943
                }
944
            }
945
        }
946
        if (taxonDescription == null){
947
            taxonDescription = TaxonDescription.NewInstance(taxon, false);
948
            if(sourceNotLinkedToElement(taxonDescription,ref,null)) {
949
                taxonDescription.addSource(OriginalSourceType.Import, null, null, ref, null);
950
            }
951
            descriptionGroup=taxonDescription;
952
            taxon.addDescription(taxonDescription);
953
        }
954

    
955
        //PREPARE REFERENCE QUESTIONS
956

    
957
        Map<String,OriginalSourceBase<?>> sourceMap = new HashMap<String, OriginalSourceBase<?>>();
958

    
959
        List<IdentifiableSource> issTmp = getCommonService().list(IdentifiableSource.class, null, null, null, null);
960
        List<DescriptionElementSource> issTmp2 = getCommonService().list(DescriptionElementSource.class, null, null, null, null);
961

    
962
        Set<OriginalSourceBase> osbSet = new HashSet<OriginalSourceBase>();
963
        if(issTmp2!=null) {
964
            osbSet.addAll(issTmp2);
965
        }
966
        if(issTmp!=null) {
967
            osbSet.addAll(issTmp);
968
        }
969

    
970

    
971
        for( OriginalSourceBase<?> osb:osbSet) {
972
            if(osb.getCitationMicroReference() !=null && !osb.getCitationMicroReference().isEmpty()) {
973
                try{
974
                    sourceMap.put(osb.getCitation().getTitleCache()+ "---"+osb.getCitationMicroReference(),osb);
975
                }catch(NullPointerException e){logger.warn("null pointer problem (no ref?) with "+osb);}
976
            } else{
977
                try{
978
                    sourceMap.put(osb.getCitation().getTitleCache(),osb);
979
                }catch(NullPointerException e){logger.warn("null pointer problem (no ref?) with "+osb);}
980
            }
981
        }
982

    
983
        if (state.getConfig().isInteractWithUser()){
984
            List<OriginalSourceBase<?>> res = null;
985
            if(!descriptionSourcesSet){
986
                res = sui.askForSource(sourceMap, "the description group ("+taxon+")",
987
                        "The current reference is "+ref.getTitleCache(),getReferenceService(), dataHolder.docSources);
988
                descriptionRefs=res;
989
                descriptionSourcesSet=true;
990
            }
991
            else{
992
                res=descriptionRefs;
993
            }
994
            if(res !=null) {
995
                for (OriginalSourceBase<?> sour:res){
996
                    if(sour.isInstanceOf(IdentifiableSource.class)){
997
                        try {
998
                            if(sourceNotLinkedToElement(taxonDescription,sour)) {
999
                                taxonDescription.addSource((IdentifiableSource)sour.clone());
1000
                            }
1001
                        } catch (CloneNotSupportedException e) {
1002
                            logger.warn("no cloning?");
1003
                        }
1004
                    }else{
1005
                        if(sourceNotLinkedToElement(taxonDescription,sour)) {
1006
                            taxonDescription.addSource(OriginalSourceType.Import,null, null, sour.getCitation(),sour.getCitationMicroReference());
1007
                        }
1008
                    }
1009
                }
1010
            }
1011
        }
1012
        else {
1013
            if(sourceNotLinkedToElement(taxonDescription,ref,null)) {
1014
                taxonDescription.addSource(OriginalSourceType.Import,null, null, ref, null);
1015
            }
1016
        }
1017
        descriptionGroup=taxonDescription;
1018

    
1019
        IndividualsAssociation indAssociation = IndividualsAssociation.NewInstance();
1020
        Feature feature = makeFeature(derivedUnitBase);
1021
        indAssociation.setAssociatedSpecimenOrObservation(derivedUnitBase);
1022
        indAssociation.setFeature(feature);
1023

    
1024
        //<<<<<<< .courant
1025
        if (state.getConfig().isInteractWithUser()){
1026
            sourceMap = new HashMap<String, OriginalSourceBase<?>>();
1027

    
1028
            issTmp = getCommonService().list(IdentifiableSource.class, null, null, null, null);
1029
            issTmp2 = getCommonService().list(DescriptionElementSource.class, null, null, null, null);
1030

    
1031
            osbSet = new HashSet<OriginalSourceBase>();
1032
            if(issTmp2!=null) {
1033
                osbSet.addAll(issTmp2);
1034
            }
1035
            if(issTmp!=null) {
1036
                osbSet.addAll(issTmp);
1037
            }
1038

    
1039

    
1040
            for( OriginalSourceBase<?> osb:osbSet) {
1041
                if(osb.getCitationMicroReference() !=null && !osb.getCitationMicroReference().isEmpty()) {
1042
                    try{
1043
                        sourceMap.put(osb.getCitation().getTitleCache()+ "---"+osb.getCitationMicroReference(),osb);
1044
                    }catch(NullPointerException e){logger.warn("null pointer problem (no ref?) with "+osb);}
1045
                } else{
1046
                    try{
1047
                        sourceMap.put(osb.getCitation().getTitleCache(),osb);
1048
                    }catch(NullPointerException e){logger.warn("null pointer problem (no ref?) with "+osb);}
1049
                }
1050
            }
1051

    
1052
            List<OriginalSourceBase<?>> sources =null;
1053
            if(!associationSourcesSet) {
1054
                sources = sui.askForSource(sourceMap,  "descriptive element (association) ",taxon.toString(),
1055
                        getReferenceService(),dataHolder.docSources);
1056
                associationRefs=sources;
1057
                associationSourcesSet=true;
1058
            }
1059
            else{
1060
                sources=associationRefs;
1061
            }
1062
            if(sources !=null) {
1063
                for (OriginalSourceBase<?> source: sources) {
1064
                    if(source !=null) {
1065
                        if(source.isInstanceOf(DescriptionElementSource.class)){
1066
                            try {
1067
                                if(sourceNotLinkedToElement(indAssociation,source)) {
1068
                                    indAssociation.addSource((DescriptionElementSource)source.clone());
1069
                                }
1070
                            } catch (CloneNotSupportedException e) {
1071
                                logger.warn("clone forbidden?");
1072
                            }
1073
                        }else{
1074
                            if(sourceNotLinkedToElement(indAssociation,source)) {
1075
                                indAssociation.addSource(OriginalSourceType.Import,null, null, source.getCitation(),source.getCitationMicroReference());
1076
                            }
1077
                            try {
1078
                                if(sourceNotLinkedToElement(derivedUnitBase, source)) {
1079
                                    derivedUnitBase.addSource((IdentifiableSource) source.clone());
1080
                                }
1081
                            } catch (CloneNotSupportedException e) {
1082
                                // TODO Auto-generated catch block
1083
                                e.printStackTrace();
1084
                            }
1085
                        }
1086

    
1087
                    }
1088
                }
1089
            }
1090
        }else {
1091
            if(sourceNotLinkedToElement(indAssociation,ref,null)) {
1092
                indAssociation.addSource(OriginalSourceType.Import,null, null, ref, null);
1093
            }
1094
            if(sourceNotLinkedToElement(derivedUnitBase, ref,null)) {
1095
                derivedUnitBase.addSource(OriginalSourceType.Import,null, null, ref, null);
1096
            }
1097
            for (Reference<?> citation : determinationEvent.getReferences()) {
1098
                if(sourceNotLinkedToElement(indAssociation,citation,null))
1099
                {
1100
                    indAssociation.addSource(DescriptionElementSource.NewInstance(OriginalSourceType.Import, null, null, citation, null));
1101
                }
1102
                if(sourceNotLinkedToElement(derivedUnitBase, ref,null)) {
1103
                    derivedUnitBase.addSource(OriginalSourceType.Import,null, null, ref, null);
1104
                }
1105
            }
1106
        }
1107

    
1108
        taxonDescription.addElement(indAssociation);
1109

    
1110
        save(taxonDescription, state);
1111
        save(taxon, state);
1112
    }
1113

    
1114

    
1115

    
1116
    /**
1117
     * @param derivedUnitBase2
1118
     * @param ref2
1119
     * @param object
1120
     * @return
1121
     */
1122
    private boolean sourceNotLinkedToElement(DerivedUnit derivedUnitBase2, Reference<?> b, String d) {
1123
        Set<IdentifiableSource> linkedSources = derivedUnitBase2.getSources();
1124
        for (IdentifiableSource is:linkedSources){
1125
            Reference a = is.getCitation();
1126
            String c = is.getCitationMicroReference();
1127

    
1128
            boolean refMatch=false;
1129
            boolean microMatch=false;
1130

    
1131
            try{
1132
                if (a==null && b==null) {
1133
                    refMatch=true;
1134
                }
1135
                if (a!=null && b!=null) {
1136
                    if (a.getTitleCache().equalsIgnoreCase(b.getTitleCache())) {
1137
                        refMatch=true;
1138
                    }
1139
                }
1140
            }catch(Exception e){}
1141

    
1142

    
1143
            try{
1144
                if (c==null && d==null) {
1145
                    microMatch=true;
1146
                }
1147
                if(c!=null && d!=null) {
1148
                    if(c.equalsIgnoreCase(d)) {
1149
                        microMatch=true;
1150
                    }
1151
                }
1152
            }
1153
            catch(Exception e){}
1154

    
1155
            if (microMatch && refMatch) {
1156
                return false;
1157
            }
1158

    
1159

    
1160
        }
1161
        return true;
1162
    }
1163

    
1164
    /**
1165
     * @param derivedUnitBase2
1166
     * @param source
1167
     * @return
1168
     */
1169
    private boolean sourceNotLinkedToElement(DerivedUnit derivedUnitBase2, OriginalSourceBase<?> source) {
1170
        Set<IdentifiableSource> linkedSources = derivedUnitBase2.getSources();
1171
        for (IdentifiableSource is:linkedSources){
1172
            Reference a = is.getCitation();
1173
            Reference b = source.getCitation();
1174
            String c = is.getCitationMicroReference();
1175
            String d = source.getCitationMicroReference();
1176

    
1177
            boolean refMatch=false;
1178
            boolean microMatch=false;
1179

    
1180
            try{
1181
                if (a==null && b==null) {
1182
                    refMatch=true;
1183
                }
1184
                if (a!=null && b!=null) {
1185
                    if (a.getTitleCache().equalsIgnoreCase(b.getTitleCache())) {
1186
                        refMatch=true;
1187
                    }
1188
                }
1189
            }catch(Exception e){}
1190

    
1191

    
1192
            try{
1193
                if (c==null && d==null) {
1194
                    microMatch=true;
1195
                }
1196
                if(c!=null && d!=null) {
1197
                    if(c.equalsIgnoreCase(d)) {
1198
                        microMatch=true;
1199
                    }
1200
                }
1201
            }
1202
            catch(Exception e){}
1203

    
1204
            if (microMatch && refMatch) {
1205
                return false;
1206
            }
1207

    
1208

    
1209
        }
1210
        return true;
1211
    }
1212

    
1213
    /**
1214
     * @param indAssociation
1215
     * @param ref2
1216
     * @param object
1217
     * @return
1218
     */
1219
    private boolean sourceNotLinkedToElement(IndividualsAssociation indAssociation, Reference<?> a, String d) {
1220
        Set<DescriptionElementSource> linkedSources = indAssociation.getSources();
1221
        for (DescriptionElementSource is:linkedSources){
1222
            Reference b = is.getCitation();
1223
            String c = is.getCitationMicroReference();
1224

    
1225
            boolean refMatch=false;
1226
            boolean microMatch=false;
1227

    
1228
            try{
1229
                if (a==null && b==null) {
1230
                    refMatch=true;
1231
                }
1232
                if (a!=null && b!=null) {
1233
                    if (a.getTitleCache().equalsIgnoreCase(b.getTitleCache())) {
1234
                        refMatch=true;
1235
                    }
1236
                }
1237
            }catch(Exception e){}
1238

    
1239

    
1240
            try{
1241
                if (c==null && d==null) {
1242
                    microMatch=true;
1243
                }
1244
                if(c!=null && d!=null) {
1245
                    if(c.equalsIgnoreCase(d)) {
1246
                        microMatch=true;
1247
                    }
1248
                }
1249
            }
1250
            catch(Exception e){}
1251

    
1252
            if (microMatch && refMatch) {
1253
                return false;
1254
            }
1255
        }
1256
        return true;
1257
    }
1258

    
1259
    /**
1260
     * @param taxonDescription
1261
     * @param ref2
1262
     * @param object
1263
     * @return
1264
     */
1265
    private boolean sourceNotLinkedToElement(TaxonDescription taxonDescription, Reference<?> a, String d) {
1266
        Set<IdentifiableSource> linkedSources = taxonDescription.getSources();
1267
        for (IdentifiableSource is:linkedSources){
1268
            Reference b = is.getCitation();
1269
            String c = is.getCitationMicroReference();
1270

    
1271
            boolean refMatch=false;
1272
            boolean microMatch=false;
1273

    
1274
            try{
1275
                if (a==null && b==null) {
1276
                    refMatch=true;
1277
                }
1278
                if (a!=null && b!=null) {
1279
                    if (a.getTitleCache().equalsIgnoreCase(b.getTitleCache())) {
1280
                        refMatch=true;
1281
                    }
1282
                }
1283
            }catch(Exception e){}
1284

    
1285

    
1286
            try{
1287
                if (c==null && d==null) {
1288
                    microMatch=true;
1289
                }
1290
                if(c!=null && d!=null) {
1291
                    if(c.equalsIgnoreCase(d)) {
1292
                        microMatch=true;
1293
                    }
1294
                }
1295
            }
1296
            catch(Exception e){}
1297

    
1298
            if (microMatch && refMatch) {
1299
                return false;
1300
            }
1301
        }
1302
        return true;
1303
    }
1304

    
1305
    /**
1306
     * @param indAssociation
1307
     * @param source
1308
     * @return
1309
     */
1310
    private boolean sourceNotLinkedToElement(IndividualsAssociation indAssociation, OriginalSourceBase<?> source) {
1311
        Set<DescriptionElementSource> linkedSources = indAssociation.getSources();
1312
        for (DescriptionElementSource is:linkedSources){
1313
            Reference a = is.getCitation();
1314
            Reference b = source.getCitation();
1315
            String c = is.getCitationMicroReference();
1316
            String d = source.getCitationMicroReference();
1317

    
1318
            boolean refMatch=false;
1319
            boolean microMatch=false;
1320

    
1321
            try{
1322
                if (a==null && b==null) {
1323
                    refMatch=true;
1324
                }
1325
                if (a!=null && b!=null) {
1326
                    if (a.getTitleCache().equalsIgnoreCase(b.getTitleCache())) {
1327
                        refMatch=true;
1328
                    }
1329
                }
1330
            }catch(Exception e){}
1331

    
1332

    
1333
            try{
1334
                if (c==null && d==null) {
1335
                    microMatch=true;
1336
                }
1337
                if(c!=null && d!=null) {
1338
                    if(c.equalsIgnoreCase(d)) {
1339
                        microMatch=true;
1340
                    }
1341
                }
1342
            }
1343
            catch(Exception e){}
1344

    
1345
            if (microMatch && refMatch) {
1346
                return false;
1347
            }
1348
        }
1349
        return true;
1350
    }
1351

    
1352
    /**
1353
     * @param taxonDescription
1354
     * @param sour
1355
     * @return
1356
     */
1357
    private boolean sourceNotLinkedToElement(TaxonDescription taxonDescription, OriginalSourceBase<?> sour) {
1358
        Set<IdentifiableSource> linkedSources = taxonDescription.getSources();
1359
        for (IdentifiableSource is:linkedSources){
1360
            Reference a = is.getCitation();
1361
            Reference b = sour.getCitation();
1362
            String c = is.getCitationMicroReference();
1363
            String d = sour.getCitationMicroReference();
1364

    
1365
            boolean refMatch=false;
1366
            boolean microMatch=false;
1367

    
1368
            try{
1369
                if (a==null && b==null) {
1370
                    refMatch=true;
1371
                }
1372
                if (a!=null && b!=null) {
1373
                    if (a.getTitleCache().equalsIgnoreCase(b.getTitleCache())) {
1374
                        refMatch=true;
1375
                    }
1376
                }
1377
            }catch(Exception e){}
1378

    
1379

    
1380
            try{
1381
                if (c==null && d==null) {
1382
                    microMatch=true;
1383
                }
1384
                if(c!=null && d!=null) {
1385
                    if(c.equalsIgnoreCase(d)) {
1386
                        microMatch=true;
1387
                    }
1388
                }
1389
            }
1390
            catch(Exception e){}
1391

    
1392
            if (microMatch && refMatch) {
1393
                return false;
1394
            }
1395

    
1396

    
1397
        }
1398
        return true;
1399
    }
1400

    
1401
    /**
1402
     * look for the Feature object (FieldObs, Specimen,...)
1403
     * @param unit : a specimen or obersvation base
1404
     * @return the corresponding Feature
1405
     */
1406
    private Feature makeFeature(SpecimenOrObservationBase<?> unit) {
1407
        SpecimenOrObservationType type = unit.getRecordBasis();
1408

    
1409

    
1410

    
1411
        if (type.isFeatureObservation()){
1412
            return Feature.OBSERVATION();
1413
        }else if (type.isFeatureSpecimen()){
1414
            return Feature.SPECIMEN();
1415
        }else if (type == SpecimenOrObservationType.DerivedUnit){
1416
            return Feature.OBSERVATION();
1417
            //            return getFeature("Specimen or observation");
1418
        }else{
1419
            String message = "Unhandled record basis '%s' for defining individuals association feature type. Use default.";
1420
            logger.warn(String.format(message, type.getMessage()));
1421
            return Feature.OBSERVATION();
1422
            //            return getFeature("Specimen or observation");
1423

    
1424
        }
1425
    }
1426

    
1427
    private Feature getFeature(String featureName, Abcd206ImportState state){
1428
        List<Feature> features = getTermService().list(Feature.class, null,null,null,null);
1429
        Feature currentFeature=null;
1430
        for (Feature feature: features){
1431
            String tmpF = feature.getTitleCache();
1432
            if (tmpF.equalsIgnoreCase(featureName)) {
1433
                currentFeature=(Feature)feature;
1434
            }
1435
        }
1436
        if (currentFeature == null) {
1437
            currentFeature=Feature.NewInstance(featureName, featureName, featureName);
1438
            save(currentFeature, state);
1439
        }
1440
        return currentFeature;
1441
    }
1442

    
1443
    /**
1444
     *  getTaxon : search for an existing taxon in the database
1445
     * @param state : the ABCD import state
1446
     * @param scientificName : the name (string)
1447
     * @param i : the current unit position in the abcd file
1448
     * @param rank : the rank for the taxon
1449
     * @return a Taxon
1450
     */
1451
    @SuppressWarnings("rawtypes")
1452
    private Taxon getTaxon(Abcd206ImportState state, String scientificName, int i, Rank rank) {
1453
//        System.out.println("GETTAXON "+scientificName);
1454
        Abcd206ImportConfigurator config = state.getConfig();
1455
        Taxon taxon = null;
1456
        NonViralName<?> taxonName = null;
1457

    
1458
        SpecimenUserInteraction sui = state.getConfig().getSpecimenUserInteraction();
1459

    
1460
//        System.out.println("config.isReuseExistingTaxaWhenPossible() :"+config.isReuseExistingTaxaWhenPossible());
1461
        if (config.isReuseExistingTaxaWhenPossible()){
1462
            List<TaxonBase> c = null;
1463
            try {
1464
                List<TaxonBase> taxonbaseList = getTaxonService().listByTitle(Taxon.class, scientificName+" sec", MatchMode.BEGINNING, null, null, null, null, null);
1465
                if (taxonbaseList.size()>0){
1466
                    if(config.isInteractWithUser() && config.isAllowReuseOtherClassifications()){
1467
                        taxon = sui.askWhereToFixData(scientificName,taxonbaseList, classification);
1468
                    } else {
1469
                        taxon = sui.lookForTaxaIntoCurrentClassification(taxonbaseList, classification);
1470
                    }
1471
                }
1472
                else{
1473
                    c = getTaxonService().searchTaxaByName(scientificName, ref);
1474
                    if(config.isInteractWithUser() && config.isAllowReuseOtherClassifications()){
1475
                        taxon = sui.askWhereToFixData(scientificName,c, classification);
1476
                    }
1477
                    else{
1478
                        taxon = sui.lookForTaxaIntoCurrentClassification(c, classification);
1479
                    }
1480
                }
1481
            } catch (Exception e) {
1482
                logger.info("Searchtaxabyname failed" + e);
1483
                taxon = null;
1484
            }
1485
        }
1486
        if (!config.isReuseExistingTaxaWhenPossible() || taxon == null){
1487
//            System.out.println("create new taxonName instance "+i+", "+config.isParseNameAutomatically());
1488
            if (config.isParseNameAutomatically()){
1489
                taxonName = parseScientificName(scientificName);
1490
            }
1491
            else{
1492
                if (i>=0 && (dataHolder.atomisedIdentificationList != null || dataHolder.atomisedIdentificationList.size() > 0)) {
1493
                    taxonName = setTaxonNameByType(dataHolder.atomisedIdentificationList.get(i), scientificName);
1494
                } else {
1495
                    taxonName=null;
1496
                }
1497
            }
1498
            //            if (taxonName != null) {
1499
            //                System.out.println(taxonName.getTitleCache());
1500
            //            } else {
1501
            //                System.out.println("taxonname: "+taxonName);
1502
            //            }
1503
            if(taxonName == null){
1504
                taxonName = NonViralName.NewInstance(rank);
1505
                taxonName.setFullTitleCache(scientificName,true);
1506
                taxonName.setTitleCache(scientificName, true);
1507
            }
1508
//            System.out.println("ADD NEW TAXON *"+taxonName.getRank()+"*"+taxonName.getTitleCache());
1509
            if (rank != null && (taxonName.getRank() ==null || taxonName.getRank().toString().trim().isEmpty())) {
1510
                taxonName.setRank(rank);
1511
            }
1512
            save(taxonName, state);
1513
            taxon = Taxon.NewInstance(taxonName, ref); //sec set null
1514
            save(taxon, state);
1515
        }
1516
        return taxon;
1517
    }
1518

    
1519

    
1520

    
1521

    
1522

    
1523

    
1524

    
1525
    /**
1526
     * HandleIdentifications : get the scientific names present in the ABCD
1527
     * document and store link them with the observation/specimen data
1528
     * @param state: the current ABCD import state
1529
     * @param derivedUnitFacade : the current derivedunitfacade
1530
     */
1531
    private void handleIdentifications(Abcd206ImportState state, DerivedUnitFacade derivedUnitFacade) {
1532
//        System.out.println("The reference from handleidentification "+ref);
1533
        Abcd206ImportConfigurator config = state.getConfig();
1534

    
1535
        String fullScientificNameString;
1536
        Taxon taxon = null;
1537
        Rank.GENUS();
1538
        Rank.FAMILY();
1539

    
1540
        String scientificName = "";
1541
        boolean preferredFlag = false;
1542

    
1543
        List<String> scientificNames = new ArrayList<String>();
1544
        if (dataHolder.nomenclatureCode == ""){
1545
            dataHolder.nomenclatureCode = config.getNomenclaturalCode().toString();
1546
        }
1547

    
1548
        for (int i = 0; i < dataHolder.identificationList.size(); i++) {
1549

    
1550
            fullScientificNameString = dataHolder.identificationList.get(i);
1551
            fullScientificNameString = fullScientificNameString.replaceAll(" et ", " & ");
1552

    
1553
            if (fullScientificNameString.indexOf(PREFERRED) != -1) {
1554
                scientificName = fullScientificNameString.split(PREFERRED)[0];
1555
                String pTmp = fullScientificNameString.split(PREFERRED)[1].split(CODE)[0];
1556
                if (pTmp.equals("1") || pTmp.toLowerCase().indexOf("true") != -1) {
1557
                    preferredFlag = true;
1558
                }
1559
                else {
1560
                    preferredFlag = false;
1561
                }
1562
            }
1563
            else {
1564
                scientificName = fullScientificNameString;
1565
            }
1566
            if(DEBUG) {
1567
                logger.info("fullscientificname " + fullScientificNameString + ", *" + dataHolder.nomenclatureCode + "*");
1568
            }
1569
            if (fullScientificNameString.indexOf(CODE) != -1) {
1570
                if (fullScientificNameString.indexOf(':') != -1) {
1571
                    dataHolder.nomenclatureCode = fullScientificNameString.split(CODE)[1].split(COLON)[1];
1572
                }
1573
                else{
1574
                    dataHolder.nomenclatureCode = fullScientificNameString.split(CODE)[1];
1575
                }
1576
            }
1577
            scientificNames.add(scientificName+SPLITTER+preferredFlag+SPLITTER+i);
1578
        }
1579
        for (String name:scientificNames) {
1580
            scientificName = name.split(SPLITTER)[0];
1581
            String pref = name.split(SPLITTER)[1];
1582
            String index = name.split(SPLITTER)[2];
1583
            if (pref.equalsIgnoreCase("true") || scientificNames.size()==1) {
1584
                preferredFlag = true;
1585
            } else {
1586
                preferredFlag =false;
1587
            }
1588
            taxon = getTaxon(state, scientificName,Integer.parseInt(index),null);
1589
            addTaxonNode(taxon, state,preferredFlag);
1590
            linkDeterminationEvent(state, taxon, preferredFlag, derivedUnitFacade);
1591
        }
1592
    }
1593

    
1594
    /**
1595
     * @param taxon : a taxon to add as a node
1596
     * @param state : the ABCD import state
1597
     */
1598
    private void addTaxonNode(Taxon taxon, Abcd206ImportState state, boolean preferredFlag) {
1599
        logger.info("link taxon to a taxonNode "+taxon.getTitleCache());
1600
        boolean exist = false;
1601
        for (TaxonNode p : classification.getAllNodes()){
1602
            try{
1603
                if(p.getTaxon().equals(taxon)) {
1604
                    exist =true;
1605
                }
1606
            }catch(Exception e){logger.warn("TaxonNode does'nt seem to have a taxon");}
1607
        }
1608
        if (!exist){
1609
            addParentTaxon(taxon, state, preferredFlag);
1610
        }
1611
    }
1612

    
1613
    /**
1614
     * Add the hierarchy for a Taxon(add higher taxa)
1615
     * @param taxon: a taxon to add as a node
1616
     * @param state: the ABCD import state
1617
     */
1618
    private void addParentTaxon(Taxon taxon, Abcd206ImportState state, boolean preferredFlag){
1619
//        System.out.println("addParentTaxon " + taxon.getTitleCache());
1620

    
1621
        NonViralName<?>  nvname = CdmBase.deproxy(taxon.getName(), NonViralName.class);
1622
        Rank rank = nvname.getRank();
1623
        Taxon genus =null;
1624
        Taxon subgenus =null;
1625
        Taxon species = null;
1626
        Taxon subspecies = null;
1627
        Taxon parent = null;
1628
        if (rank.isLower(Rank.GENUS() )){
1629
            String prefix = nvname.getGenusOrUninomial();
1630
            genus = getTaxon(state, prefix, -1, Rank.GENUS());
1631
            if (preferredFlag) {
1632
                parent = saveOrUpdateClassification(null, genus, state);
1633
            }
1634

    
1635
        }
1636
        if (rank.isLower(Rank.SUBGENUS())){
1637
            String prefix = nvname.getGenusOrUninomial();
1638
            String name = nvname.getInfraGenericEpithet();
1639
            if (name != null){
1640
                subgenus = getTaxon(state, prefix+" "+name, -1, Rank.SUBGENUS());
1641
                if (preferredFlag) {
1642
                    parent = saveOrUpdateClassification(genus, subgenus, state);
1643
                }            }
1644
        }
1645
        if (rank.isLower(Rank.SPECIES())){
1646
            if (subgenus!=null){
1647
                String prefix = nvname.getGenusOrUninomial();
1648
                String name = nvname.getInfraGenericEpithet();
1649
                String spe = nvname.getSpecificEpithet();
1650
                if (spe != null){
1651
                    species = getTaxon(state, prefix+" "+name+" "+spe, -1, Rank.SPECIES());
1652
                    if (preferredFlag) {
1653
                        parent = 	saveOrUpdateClassification(subgenus, species, state);
1654
                    }
1655
                }
1656
            }
1657
            else{
1658
                String prefix = nvname.getGenusOrUninomial();
1659
                String name = nvname.getSpecificEpithet();
1660
                if (name != null){
1661
                    species = getTaxon(state, prefix+" "+name, -1, Rank.SPECIES());
1662
                    if (preferredFlag) {
1663
                        parent = 	saveOrUpdateClassification(genus, species, state);
1664
                    }
1665
                }
1666
            }
1667
        }
1668
        if (rank.isInfraSpecific()){
1669
            subspecies = getTaxon(state, nvname.getFullTitleCache(), -1, Rank.SUBSPECIES());
1670
            if (preferredFlag) {
1671
                parent = 	saveOrUpdateClassification(species, subspecies, state);
1672
            }
1673
        }
1674
        if (preferredFlag) {
1675
            saveOrUpdateClassification(parent, taxon, state);
1676
        }
1677
    }
1678

    
1679
    /**
1680
     * Link a parent to a child and save it in the current classification
1681
     * @param parent: the higher Taxon
1682
     * @param child : the lower (or current) Taxon
1683
     * return the Taxon from the new created Node
1684
     * @param state
1685
     */
1686
    private Taxon saveOrUpdateClassification(Taxon parent, Taxon child, Abcd206ImportState state) {
1687
//        System.out.println("ADD CLASSIFICATION parent child "+parent+"," +child);
1688
        TaxonNode node =null;
1689
        if (parent != null) {
1690
            parent = (Taxon) getTaxonService().find(parent.getUuid());
1691
            child = (Taxon) getTaxonService().find(child.getUuid());
1692
            node = classification.addParentChild(parent, child, ref, "");
1693
        }
1694
        if (parent == null) {
1695
            child = (Taxon) getTaxonService().find(child.getUuid());
1696
            node =classification.addChildTaxon(child, ref, null);
1697
        }
1698
        save(classification, state);
1699
        return node.getTaxon();
1700
    }
1701

    
1702
    /**
1703
     * Parse automatically the scientific name
1704
     * @param scientificName: the scientific name to parse
1705
     * @return a parsed name
1706
     */
1707
    private NonViralName<?> parseScientificName(String scientificName) {
1708
        NonViralNameParserImpl nvnpi = NonViralNameParserImpl.NewInstance();
1709
        NonViralName<?> taxonName = null;
1710
        boolean problem = false;
1711

    
1712
        if(DEBUG){
1713
            logger.info("parseScientificName " + dataHolder.nomenclatureCode.toString());
1714
        }
1715

    
1716
        if (dataHolder.nomenclatureCode.toString().equals("Zoological") || dataHolder.nomenclatureCode.toString().contains("ICZN")) {
1717
            taxonName = nvnpi.parseFullName(scientificName, NomenclaturalCode.ICZN, null);
1718
            if (taxonName.hasProblem()) {
1719
                problem = true;
1720
            }
1721
        }
1722
        if (dataHolder.nomenclatureCode.toString().equals("Botanical") || dataHolder.nomenclatureCode.toString().contains("ICBN")) {
1723
            taxonName = nvnpi.parseFullName(scientificName, NomenclaturalCode.ICNAFP, null);
1724
            if (taxonName.hasProblem()) {
1725
                problem = true;
1726
            }
1727
        }
1728
        if (dataHolder.nomenclatureCode.toString().equals("Bacterial") || dataHolder.nomenclatureCode.toString().contains("ICBN")) {
1729
            taxonName = nvnpi.parseFullName(scientificName, NomenclaturalCode.ICNB, null);
1730
            if (taxonName.hasProblem()) {
1731
                problem = true;
1732
            }
1733
        }
1734
        if (dataHolder.nomenclatureCode.toString().equals("Cultivar") || dataHolder.nomenclatureCode.toString().contains("ICNCP")) {
1735
            taxonName = nvnpi.parseFullName(scientificName, NomenclaturalCode.ICNCP, null);
1736
            if (taxonName.hasProblem()) {
1737
                problem = true;
1738
            }
1739
        }
1740
        if (problem) {
1741
            logger.info("Parsing with problem in parseScientificName " + scientificName);
1742
            return null;
1743
        }
1744
        return taxonName;
1745

    
1746
    }
1747

    
1748
    /**
1749
     * Create the name without automatic parsing, either because it failed, or because the user deactivated it.
1750
     * The name is built upon the ABCD fields
1751
     * @param atomisedMap : the ABCD atomised fields
1752
     * @param fullName : the full scientific name
1753
     * @return the corresponding Botanical or Zoological or... name
1754
     */
1755
    private NonViralName<?> setTaxonNameByType(
1756
            HashMap<String, String> atomisedMap, String fullName) {
1757
        boolean problem = false;
1758
        if(DEBUG) {
1759
            logger.info("settaxonnamebytype " + dataHolder.nomenclatureCode.toString());
1760
        }
1761

    
1762
        if (dataHolder.nomenclatureCode.equals("Zoological")) {
1763
            NonViralName<ZoologicalName> taxonName = ZoologicalName.NewInstance(null);
1764
            taxonName.setFullTitleCache(fullName, true);
1765
            taxonName.setGenusOrUninomial(NB(getFromMap(atomisedMap, "Genus")));
1766
            taxonName.setInfraGenericEpithet(NB(getFromMap(atomisedMap, "SubGenus")));
1767
            taxonName.setSpecificEpithet(NB(getFromMap(atomisedMap,"SpeciesEpithet")));
1768
            taxonName.setInfraSpecificEpithet(NB(getFromMap(atomisedMap,"SubspeciesEpithet")));
1769

    
1770
            if (taxonName.getGenusOrUninomial() != null){
1771
                taxonName.setRank(Rank.GENUS());
1772
            }
1773

    
1774
            if (taxonName.getInfraGenericEpithet() != null){
1775
                taxonName.setRank(Rank.SUBGENUS());
1776
            }
1777

    
1778
            if (taxonName.getSpecificEpithet() != null){
1779
                taxonName.setRank(Rank.SPECIES());
1780
            }
1781

    
1782
            if (taxonName.getInfraSpecificEpithet() != null){
1783
                taxonName.setRank(Rank.SUBSPECIES());
1784
            }
1785

    
1786
            Team team = null;
1787
            if (getFromMap(atomisedMap, "AuthorTeamParenthesis") != null) {
1788
                team = Team.NewInstance();
1789
                team.setTitleCache(getFromMap(atomisedMap, "AuthorTeamParenthesis"), true);
1790
            }
1791
            else {
1792
                if (getFromMap(atomisedMap, "AuthorTeamAndYear") != null) {
1793
                    team = Team.NewInstance();
1794
                    team.setTitleCache(getFromMap(atomisedMap, "AuthorTeamAndYear"), true);
1795
                }
1796
            }
1797
            if (team != null) {
1798
                taxonName.setBasionymAuthorTeam(team);
1799
            }
1800
            else {
1801
                if (getFromMap(atomisedMap, "AuthorTeamParenthesis") != null) {
1802
                    taxonName.setAuthorshipCache(getFromMap(atomisedMap, "AuthorTeamParenthesis"));
1803
                }
1804
                else if (getFromMap(atomisedMap, "AuthorTeamAndYear") != null) {
1805
                    taxonName.setAuthorshipCache(getFromMap(atomisedMap, "AuthorTeamAndYear"));
1806
                }
1807
            }
1808
            if (getFromMap(atomisedMap, "CombinationAuthorTeamAndYear") != null) {
1809
                team = Team.NewInstance();
1810
                team.setTitleCache(getFromMap(atomisedMap, "CombinationAuthorTeamAndYear"), true);
1811
                taxonName.setCombinationAuthorTeam(team);
1812
            }
1813
            if (taxonName.hasProblem()) {
1814
                logger.info("pb ICZN");
1815
                problem = true;
1816
            }
1817
            else {
1818
                return taxonName;
1819
            }
1820
        }
1821
        else if (dataHolder.nomenclatureCode.equals("Botanical")) {
1822
            BotanicalName taxonName = (BotanicalName) parseScientificName(fullName);
1823
            if (taxonName != null){
1824
                return taxonName;
1825
            }
1826
            else{
1827
                taxonName = BotanicalName.NewInstance(null);
1828
            }
1829
            taxonName.setFullTitleCache(fullName, true);
1830
            taxonName.setGenusOrUninomial(NB(getFromMap(atomisedMap, "Genus")));
1831
            taxonName.setInfraGenericEpithet(NB(getFromMap(atomisedMap, "FirstEpithet")));
1832
            taxonName.setInfraSpecificEpithet(NB(getFromMap(atomisedMap, "InfraSpeEpithet")));
1833
            try {
1834
                taxonName.setRank(Rank.getRankByName(getFromMap(atomisedMap, "Rank")));
1835
            } catch (Exception e) {
1836
                if (taxonName.getGenusOrUninomial() != null){
1837
                    taxonName.setRank(Rank.GENUS());
1838
                }
1839
                else if (taxonName.getInfraGenericEpithet() != null){
1840
                    taxonName.setRank(Rank.SUBGENUS());
1841
                }
1842
                else if (taxonName.getSpecificEpithet() != null){
1843
                    taxonName.setRank(Rank.SPECIES());
1844
                }
1845
                else if (taxonName.getInfraSpecificEpithet() != null){
1846
                    taxonName.setRank(Rank.SUBSPECIES());
1847
                }
1848
            }
1849
            Team team = null;
1850
            if (getFromMap(atomisedMap, "AuthorTeamParenthesis") != null) {
1851
                team = Team.NewInstance();
1852
                team.setTitleCache(getFromMap(atomisedMap, "AuthorTeamParenthesis"), true);
1853
                taxonName.setBasionymAuthorTeam(team);
1854
            }
1855
            if (getFromMap(atomisedMap, "AuthorTeam") != null) {
1856
                team = Team.NewInstance();
1857
                team.setTitleCache(getFromMap(atomisedMap, "AuthorTeam"), true);
1858
                taxonName.setCombinationAuthorTeam(team);
1859
            }
1860
            if (team == null) {
1861
                if (getFromMap(atomisedMap, "AuthorTeamParenthesis") != null) {
1862
                    taxonName.setAuthorshipCache(getFromMap(atomisedMap, "AuthorTeamParenthesis"));
1863
                }
1864
                else if (getFromMap(atomisedMap, "AuthorTeam") != null) {
1865
                    taxonName.setAuthorshipCache(getFromMap(atomisedMap, "AuthorTeam"));
1866
                }
1867
            }
1868
            if (getFromMap(atomisedMap, "CombinationAuthorTeamAndYear") != null) {
1869
                team = Team.NewInstance();
1870
                team.setTitleCache(getFromMap(atomisedMap, "CombinationAuthorTeamAndYear"), true);
1871
                taxonName.setCombinationAuthorTeam(team);
1872
            }
1873
            if (taxonName.hasProblem()) {
1874
                logger.info("pb ICBN");
1875
                problem = true;
1876
            }
1877
            else {
1878
                return taxonName;
1879
            }
1880
        }
1881
        else if (dataHolder.nomenclatureCode.equals("Bacterial")) {
1882
            NonViralName<BacterialName> taxonName = BacterialName.NewInstance(null);
1883
            taxonName.setFullTitleCache(fullName, true);
1884
            taxonName.setGenusOrUninomial(getFromMap(atomisedMap, "Genus"));
1885
            taxonName.setInfraGenericEpithet(NB(getFromMap(atomisedMap, "SubGenus")));
1886
            taxonName.setSpecificEpithet(NB(getFromMap(atomisedMap, "Species")));
1887
            taxonName.setInfraSpecificEpithet(NB(getFromMap(atomisedMap, "SubspeciesEpithet")));
1888

    
1889
            if (taxonName.getGenusOrUninomial() != null){
1890
                taxonName.setRank(Rank.GENUS());
1891
            }
1892
            else if (taxonName.getInfraGenericEpithet() != null){
1893
                taxonName.setRank(Rank.SUBGENUS());
1894
            }
1895
            else if (taxonName.getSpecificEpithet() != null){
1896
                taxonName.setRank(Rank.SPECIES());
1897
            }
1898
            else if (taxonName.getInfraSpecificEpithet() != null){
1899
                taxonName.setRank(Rank.SUBSPECIES());
1900
            }
1901

    
1902
            if (getFromMap(atomisedMap, "AuthorTeamAndYear") != null) {
1903
                Team team = Team.NewInstance();
1904
                team.setTitleCache(getFromMap(atomisedMap, "AuthorTeamAndYear"), true);
1905
                taxonName.setCombinationAuthorTeam(team);
1906
            }
1907
            if (getFromMap(atomisedMap, "ParentheticalAuthorTeamAndYear") != null) {
1908
                Team team = Team.NewInstance();
1909
                team.setTitleCache(getFromMap(atomisedMap, "ParentheticalAuthorTeamAndYear"), true);
1910
                taxonName.setBasionymAuthorTeam(team);
1911
            }
1912
            if (taxonName.hasProblem()) {
1913
                logger.info("pb ICNB");
1914
                problem = true;
1915
            }
1916
            else {
1917
                return taxonName;
1918
            }
1919
        }
1920
        else if (dataHolder.nomenclatureCode.equals("Cultivar")) {
1921
            CultivarPlantName taxonName = CultivarPlantName.NewInstance(null);
1922

    
1923
            if (taxonName.hasProblem()) {
1924
                logger.info("pb ICNCP");
1925
                problem = true;
1926
            }
1927
            else {
1928
                return taxonName;
1929
            }
1930
            return taxonName;
1931
        }
1932

    
1933
        if (problem) {
1934
            logger.info("Problem im setTaxonNameByType ");
1935
            NonViralName<?> taxonName = NonViralName.NewInstance(null);
1936
            taxonName.setFullTitleCache(fullName, true);
1937
            return taxonName;
1938
        }
1939
        NonViralName<?> tn = NonViralName.NewInstance(null);
1940
        return tn;
1941
    }
1942

    
1943

    
1944
    /**
1945
     * Get a formated string from a hashmap
1946
     * @param atomisedMap
1947
     * @param key
1948
     * @return
1949
     */
1950
    private String getFromMap(HashMap<String, String> atomisedMap, String key) {
1951
        String value = null;
1952
        if (atomisedMap.containsKey(key)) {
1953
            value = atomisedMap.get(key);
1954
        }
1955

    
1956
        try {
1957
            if (value != null && key.matches(".*Year.*")) {
1958
                value = value.trim();
1959
                if (value.matches("[a-z A-Z ]*[0-9]{4}$")) {
1960
                    String tmp = value.split("[0-9]{4}$")[0];
1961
                    int year = Integer.parseInt(value.split(tmp)[1]);
1962
                    if (year >= 1752) {
1963
                        value = tmp;
1964
                    }
1965
                    else {
1966
                        value = null;
1967
                    }
1968
                }
1969
                else {
1970
                    value = null;
1971
                }
1972
            }
1973
        }
1974
        catch (Exception e) {
1975
            value = null;
1976
        }
1977
        return value;
1978
    }
1979

    
1980
    //    private void compareABCDtoCDM(URI urlFileName, List<String> knownElts, Abcd206XMLFieldGetter abcdFieldGetter) {
1981
    //        try {
1982
    //            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
1983
    //            DocumentBuilder constructeur = factory.newDocumentBuilder();
1984
    //            URL url = urlFileName.toURL();
1985
    //            Object o = url.getContent();
1986
    //            InputStream is = (InputStream) o;
1987
    //            Document document = constructeur.parse(is);
1988
    //            Element root = document.getDocumentElement();
1989
    //            abcdFieldGetter.traverse(root);
1990
    //        }
1991
    //        catch (ParserConfigurationException e){
1992
    //            e.printStackTrace();
1993
    //        }
1994
    //        catch (SAXException e) {
1995
    //            e.printStackTrace();
1996
    //        }
1997
    //        catch (IOException e) {
1998
    //            e.printStackTrace();
1999
    //        }
2000
    //        Set<String> elts = dataHolder.allABCDelements.keySet();
2001
    //        Iterator<String> it = elts.iterator();
2002
    //        String elt;
2003
    //        while (it.hasNext()) {
2004
    //            elt = it.next();
2005
    //            if (knownElts.indexOf(elt) == -1) {
2006
    //                if(DEBUG) {
2007
    //                    logger.info("Unmerged ABCD element: " + elt + " - "+ dataHolder.allABCDelements.get(elt));
2008
    //                }
2009
    //            }
2010
    //        }
2011
    //    }
2012

    
2013
    /**
2014
     * Load the list of names from the ABCD file and save them
2015
     * @param state : the current ABCD import state
2016
     * @param unitsList : the unit list from the ABCD file
2017
     * @param abcdFieldGetter : the ABCD parser
2018
     */
2019
    private void prepareCollectors(Abcd206ImportState state, NodeList unitsList, Abcd206XMLFieldGetter abcdFieldGetter) {
2020
        List<String> collectors = new ArrayList<String>();
2021
        List<String> teams = new ArrayList<String>();
2022
        List<List<String>> collectorinteams = new ArrayList<List<String>>();
2023

    
2024
        for (int i = 0; i < unitsList.getLength(); i++) {
2025
            this.getCollectorsFromXML((Element) unitsList.item(i), abcdFieldGetter);
2026
            for (String agent : dataHolder.gatheringAgentList) {
2027
                collectors.add(agent);
2028
            }
2029
            List<String> tmpTeam = new ArrayList<String>(new HashSet<String>(dataHolder.gatheringTeamList));
2030
            if(!tmpTeam.isEmpty()) {
2031
                teams.add(StringUtils.join(tmpTeam.toArray()," & "));
2032
            }
2033
            for (String agent:tmpTeam) {
2034
                collectors.add(agent);
2035
            }
2036
        }
2037

    
2038
        List<String> collectorsU = new ArrayList<String>(new HashSet<String>(collectors));
2039
        List<String> teamsU = new ArrayList<String>(new HashSet<String>(teams));
2040

    
2041

    
2042
        //existing teams in DB
2043
        Map<String,Team> titleCacheTeam = new HashMap<String, Team>();
2044
        List<UuidAndTitleCache<Team>> hiberTeam = getAgentService().getTeamUuidAndTitleCache();
2045

    
2046
        Set<UUID> uuids = new HashSet<UUID>();
2047
        for (UuidAndTitleCache<Team> hibernateT:hiberTeam){
2048
            uuids.add(hibernateT.getUuid());
2049
        }
2050
        if (!uuids.isEmpty()){
2051
            List<AgentBase> existingTeams = getAgentService().find(uuids);
2052
            for (AgentBase<?> existingP:existingTeams){
2053
                titleCacheTeam.put(existingP.getTitleCache(),CdmBase.deproxy(existingP,Team.class));
2054
            }
2055
        }
2056

    
2057

    
2058
        Map<String,UUID> teamMap = new HashMap<String, UUID>();
2059
        for (UuidAndTitleCache<Team> uuidt:hiberTeam){
2060
            teamMap.put(uuidt.getTitleCache(), uuidt.getUuid());
2061
        }
2062

    
2063
        //existing persons in DB
2064
        List<UuidAndTitleCache<Person>> hiberPersons = getAgentService().getPersonUuidAndTitleCache();
2065
        Map<String,Person> titleCachePerson = new HashMap<String, Person>();
2066
        uuids = new HashSet<UUID>();
2067
        for (UuidAndTitleCache<Person> hibernateP:hiberPersons){
2068
            uuids.add(hibernateP.getUuid());
2069
        }
2070

    
2071
        if (!uuids.isEmpty()){
2072
            List<AgentBase> existingPersons = getAgentService().find(uuids);
2073
            for (AgentBase<?> existingP:existingPersons){
2074
                titleCachePerson.put(existingP.getTitleCache(),CdmBase.deproxy(existingP,Person.class));
2075
            }
2076
        }
2077

    
2078
        Map<String,UUID> personMap = new HashMap<String, UUID>();
2079
        for (UuidAndTitleCache<Person> person:hiberPersons){
2080
            personMap.put(person.getTitleCache(), person.getUuid());
2081
        }
2082

    
2083
        java.util.Collection<Person> personToadd = new ArrayList<Person>();
2084
        java.util.Collection<Team> teamToAdd = new ArrayList<Team>();
2085

    
2086
        for (String collector:collectorsU){
2087
            Person p = Person.NewInstance();
2088
            p.setTitleCache(collector,true);
2089
            if (!personMap.containsKey(p.getTitleCache())){
2090
                personToadd.add(p);
2091
            }
2092
        }
2093
        for (String team:teamsU){
2094
            Team p = Team.NewInstance();
2095
            p.setTitleCache(team,true);
2096
            if (!teamMap.containsKey(p.getTitleCache())){
2097
                teamToAdd.add(p);
2098
            }
2099
        }
2100

    
2101
        if(!personToadd.isEmpty()){
2102
            for (Person agent: personToadd){
2103
                save(agent, state);
2104
                titleCachePerson.put(agent.getTitleCache(),CdmBase.deproxy(agent, Person.class) );
2105
            }
2106
        }
2107

    
2108
        Person ptmp ;
2109
        Map <String,Integer>teamdone = new HashMap<String, Integer>();
2110
        for (List<String> collteam: collectorinteams){
2111
            if (!teamdone.containsKey(StringUtils.join(collteam.toArray(),"-"))){
2112
                Team team = new Team();
2113
                boolean em =true;
2114
                for (String collector:collteam){
2115
                    ptmp = Person.NewInstance();
2116
                    ptmp.setTitleCache(collector,true);
2117
                    Person p2 = titleCachePerson.get(ptmp.getTitleCache());
2118
                    team.addTeamMember(p2);
2119
                    em=false;
2120
                }
2121
                if (!em) {
2122
                    teamToAdd.add(team);
2123
                }
2124
                teamdone.put(StringUtils.join(collteam.toArray(),"-"),0);
2125
            }
2126
        }
2127

    
2128
        if(!teamToAdd.isEmpty()){
2129
            for (Team agent: teamToAdd){
2130
                save(agent, state);
2131
                titleCacheTeam.put(agent.getTitleCache(), CdmBase.deproxy( agent,Team.class) );
2132
            }
2133
        }
2134

    
2135
        state.getConfig().setTeams(titleCacheTeam);
2136
        state.getConfig().setPersons(titleCachePerson);
2137
    }
2138

    
2139
    @Override
2140
    protected boolean isIgnore(Abcd206ImportState state) {
2141
        return false;
2142
    }
2143

    
2144

    
2145
}
(2-2/5)