Project

General

Profile

Download (84.1 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
//=======
49
import eu.etaxonomy.cdm.model.common.LanguageString;
50
//<<<<<<< .courant
51
import eu.etaxonomy.cdm.model.common.OriginalSourceBase;
52
import eu.etaxonomy.cdm.model.common.OriginalSourceType;
53
//>>>>>>> .fusion-droit.r19057
54
import eu.etaxonomy.cdm.model.common.UuidAndTitleCache;
55
import eu.etaxonomy.cdm.model.description.DescriptionBase;
56
import eu.etaxonomy.cdm.model.description.DescriptionElementSource;
57
import eu.etaxonomy.cdm.model.description.Feature;
58
import eu.etaxonomy.cdm.model.description.IndividualsAssociation;
59
import eu.etaxonomy.cdm.model.description.TaxonDescription;
60
import eu.etaxonomy.cdm.model.location.NamedArea;
61
import eu.etaxonomy.cdm.model.media.Media;
62
import eu.etaxonomy.cdm.model.name.BacterialName;
63
import eu.etaxonomy.cdm.model.name.BotanicalName;
64
import eu.etaxonomy.cdm.model.name.CultivarPlantName;
65
import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
66
import eu.etaxonomy.cdm.model.name.NonViralName;
67
import eu.etaxonomy.cdm.model.name.Rank;
68
import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;
69
import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignationStatus;
70
import eu.etaxonomy.cdm.model.name.TaxonNameBase;
71
import eu.etaxonomy.cdm.model.name.ZoologicalName;
72
import eu.etaxonomy.cdm.model.occurrence.Collection;
73
import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
74
import eu.etaxonomy.cdm.model.occurrence.DeterminationEvent;
75
import eu.etaxonomy.cdm.model.occurrence.GatheringEvent;
76
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
77
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationType;
78
import eu.etaxonomy.cdm.model.reference.Reference;
79
import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
80
import eu.etaxonomy.cdm.model.taxon.Classification;
81
import eu.etaxonomy.cdm.model.taxon.Taxon;
82
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
83
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
84
import eu.etaxonomy.cdm.persistence.query.MatchMode;
85
import eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl;
86

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

    
95

    
96
    private final boolean DEBUG = true;
97

    
98
    private static final String PREFERRED = "_preferred_";
99
    private static final String CODE = "_code_";
100
    private static final String COLON = ":";
101
    private static final String SPLITTER = "--";
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

    
120
    public Abcd206Import() {
121
        super();
122
    }
123

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

    
130

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

    
137
        SpecimenUserInteraction sui = state.getConfig().getSpecimenUserInteraction();
138

    
139
        List<Reference> references = getReferenceService().list(Reference.class, null, null, null, null);
140

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

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

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

    
220
        InputStream source = state.getConfig().getSource();
221
        NodeList unitsList = getUnitsNodeList(source);
222

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

    
228
            dataHolder = new Abcd206DataHolder();
229

    
230
            Abcd206XMLFieldGetter abcdFieldGetter = new Abcd206XMLFieldGetter(dataHolder, prefix);
231

    
232
            prepareCollectors(state, unitsList, abcdFieldGetter);
233

    
234
            for (int i = 0; i < unitsList.getLength(); i++) {
235
                System.out.println("------------------------------------------------------------------------------------------");
236
                associationRefs = new ArrayList<OriginalSourceBase<?>>();
237
                descriptionRefs = new ArrayList<OriginalSourceBase<?>>();
238
                derivedUnitSources = new ArrayList<OriginalSourceBase<?>>();
239

    
240
                this.setUnitPropertiesXML( (Element) unitsList.item(i), abcdFieldGetter);
241
                //				refreshTransaction(state);
242
                this.handleSingleUnit(state);
243

    
244
                // compare the ABCD elements added in to the CDM and the
245
                // unhandled ABCD elements
246
                //compareABCDtoCDM(sourceName, dataHolder.knownABCDelements, abcdFieldGetter);
247

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

    
258
    }
259

    
260

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

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

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

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

    
307
            // create facade
308
            DerivedUnitFacade derivedUnitFacade = getFacade();
309
            derivedUnitBase = derivedUnitFacade.innerDerivedUnit();
310

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

    
318
            // country
319
            UnitsGatheringArea unitsGatheringArea = new UnitsGatheringArea();
320
            //  unitsGatheringArea.setConfig(state.getConfig(),getOccurrenceService(), getTermService());
321
            unitsGatheringArea.setParams(dataHolder.isocountry, dataHolder.country, state.getConfig(), getTermService(), getOccurrenceService());
322

    
323
            DefinedTermBase<?> areaCountry =  unitsGatheringArea.getCountry();
324

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

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

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

    
347
            // add fieldNumber
348
            derivedUnitFacade.setFieldNumber(NB(dataHolder.fieldNumber));
349

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

    
362
                }
363
            }
364

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

    
374
            save(unitsGatheringEvent.getLocality(), state);
375

    
376
            // handle collection data
377
            setCollectionData(state, derivedUnitFacade);
378

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

    
383
            dataHolder.docSources = new ArrayList<String>();
384
            for (String[] fullReference : dataHolder.referenceList) {
385
                System.out.println("referenceFullList "+fullReference);
386
                String strReference=fullReference[0];
387
                String citationDetail = fullReference[1];
388
                String citationURL = fullReference[2];
389

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

    
394
                Reference<?> reference = ReferenceFactory.newGeneric();
395
                reference.setTitleCache(strReference);
396
                System.out.println("reference has problem?" +reference.hasProblem());
397

    
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
                //TODO what do we need tmp for?
413
                String tmp = sour.getCitation().getTitleCache();
414
                if (StringUtils.isNotBlank(sour.getCitationMicroReference())) {
415
                    tmp +=" ("+sour.getCitationMicroReference()+")";
416
                }
417
                reference.addSource(sour);
418
                getReferenceService().saveOrUpdate(reference);
419
            }
420

    
421

    
422
            List<OriginalSourceBase> issTmp = getCommonService().list(IdentifiableSource.class, null, null, null, null);
423
            List<OriginalSourceBase> issTmp2 = getCommonService().list(DescriptionElementSource.class, null, null, null, null);
424

    
425
            Set<OriginalSourceBase> osbSet = new HashSet<OriginalSourceBase>();
426
            if(issTmp2!=null) {
427
                osbSet.addAll(issTmp2);
428
            }
429
            if(issTmp!=null) {
430
                osbSet.addAll(issTmp);
431
            }
432

    
433

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

    
446
            if( state.getConfig().isInteractWithUser()){
447
                List<OriginalSourceBase<?>>sources=null;
448
                if(!derivedUnitSourcesSet){
449
                    sources= sui.askForSource(sourceMap, "the unit itself","",getReferenceService(), dataHolder.docSources);
450
                    derivedUnitSources=sources;
451
                    derivedUnitSourcesSet=true;
452
                }
453
                else{
454
                    sources=derivedUnitSources;
455
                }
456
                for (OriginalSourceBase<?> sour:sources){
457
                    if(sour.isInstanceOf(IdentifiableSource.class)){
458
                        if(sourceNotLinkedToElement(derivedUnitFacade,sour)) {
459
                            derivedUnitFacade.addSource((IdentifiableSource)sour.clone());
460
                        }
461
                    }else{
462
                        if(sourceNotLinkedToElement(derivedUnitFacade,sour)) {
463
                            derivedUnitFacade.addSource(OriginalSourceType.Import,sour.getCitation(),sour.getCitationMicroReference(), ioName);
464
                        }
465
                    }
466
                }
467
            }else{
468
                for (OriginalSourceBase<?> sr : sourceMap.values()){
469
                    if(sr.isInstanceOf(IdentifiableSource.class)){
470
                        if(sourceNotLinkedToElement(derivedUnitFacade,sr)) {
471
                            derivedUnitFacade.addSource((IdentifiableSource)sr.clone());
472
                        }
473
                    }else{
474
                        if(sourceNotLinkedToElement(derivedUnitFacade,sr)) {
475
                            derivedUnitFacade.addSource(OriginalSourceType.Import,sr.getCitation(),sr.getCitationMicroReference(), ioName);
476
                        }
477
                    }
478
                }
479
            }
480

    
481
            getOccurrenceService().saveOrUpdate(derivedUnitBase);
482

    
483
            //=======
484
            save(derivedUnitBase, state);
485

    
486
            // handle identifications
487
            handleIdentifications(state, derivedUnitFacade);
488

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

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

    
499
        return;
500
    }
501

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

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

    
531
        List<OriginalSourceBase> issTmp = getCommonService().list(IdentifiableSource.class, null, null, null, null);
532

    
533

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

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

    
557
    /**
558
     * @param reference
559
     * @param citationDetail
560
     * @return
561
     */
562
    private DescriptionElementSource getDescriptionSource(Reference<?> reference, String citationDetail) {
563

    
564
        List<OriginalSourceBase> issTmp2 = getCommonService().list(DescriptionElementSource.class, null, null, null, null);
565

    
566
        try {
567
            for (OriginalSourceBase<?> osb:issTmp2){
568
                if (osb.getCitation().equals(reference) && osb.getCitationMicroReference().equalsIgnoreCase(citationDetail)) {
569
                    return (DescriptionElementSource) osb.clone();
570
                }
571
            }
572
        } catch (CloneNotSupportedException e) {
573
            // TODO Auto-generated catch block
574
            e.printStackTrace();
575
        }
576

    
577
        DescriptionElementSource sour = DescriptionElementSource.NewInstance(OriginalSourceType.Import,null,null, reference,citationDetail);
578
        return sour;
579
    }
580

    
581

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

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

    
619
    }
620

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

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

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

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

    
682
    private void getCollectorsFromXML(Element root, Abcd206XMLFieldGetter abcdFieldGetter) {
683
        NodeList group;
684

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

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

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

    
722
            abcdFieldGetter.getScientificNames(group);
723
            abcdFieldGetter.getType(root);
724

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

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

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

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

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

    
821

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
947
        //PREPARE REFERENCE QUESTIONS
948

    
949
        Map<String,OriginalSourceBase<?>> sourceMap = new HashMap<String, OriginalSourceBase<?>>();
950

    
951
        List<OriginalSourceBase> issTmp = getCommonService().list(IdentifiableSource.class, null, null, null, null);
952
        List<OriginalSourceBase> issTmp2 = getCommonService().list(DescriptionElementSource.class, null, null, null, null);
953

    
954
        Set<OriginalSourceBase> osbSet = new HashSet<OriginalSourceBase>();
955
        if(issTmp2!=null) {
956
            osbSet.addAll(issTmp2);
957
        }
958
        if(issTmp!=null) {
959
            osbSet.addAll(issTmp);
960
        }
961

    
962

    
963
        for( OriginalSourceBase<?> osb:osbSet) {
964
            if(osb.getCitationMicroReference() !=null && !osb.getCitationMicroReference().isEmpty()) {
965
                try{
966
                    sourceMap.put(osb.getCitation().getTitleCache()+ "---"+osb.getCitationMicroReference(),osb);
967
                }catch(NullPointerException e){logger.warn("null pointer problem (no ref?) with "+osb);}
968
            } else{
969
                try{
970
                    sourceMap.put(osb.getCitation().getTitleCache(),osb);
971
                }catch(NullPointerException e){logger.warn("null pointer problem (no ref?) with "+osb);}
972
            }
973
        }
974

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

    
1010
        IndividualsAssociation indAssociation = IndividualsAssociation.NewInstance();
1011
        Feature feature = makeFeature(derivedUnitBase);
1012
        indAssociation.setAssociatedSpecimenOrObservation(derivedUnitBase);
1013
        indAssociation.setFeature(feature);
1014

    
1015
        //<<<<<<< .courant
1016
        if (state.getConfig().isInteractWithUser()){
1017
            sourceMap = new HashMap<String, OriginalSourceBase<?>>();
1018

    
1019
            issTmp = getCommonService().list(IdentifiableSource.class, null, null, null, null);
1020
            issTmp2 = getCommonService().list(DescriptionElementSource.class, null, null, null, null);
1021

    
1022
            osbSet = new HashSet<OriginalSourceBase>();
1023
            if(issTmp2!=null) {
1024
                osbSet.addAll(issTmp2);
1025
            }
1026
            if(issTmp!=null) {
1027
                osbSet.addAll(issTmp);
1028
            }
1029

    
1030

    
1031
            for( OriginalSourceBase<?> osb:osbSet) {
1032
                if(osb.getCitationMicroReference() !=null && !osb.getCitationMicroReference().isEmpty()) {
1033
                    try{
1034
                        sourceMap.put(osb.getCitation().getTitleCache()+ "---"+osb.getCitationMicroReference(),osb);
1035
                    }catch(NullPointerException e){logger.warn("null pointer problem (no ref?) with "+osb);}
1036
                } else{
1037
                    try{
1038
                        sourceMap.put(osb.getCitation().getTitleCache(),osb);
1039
                    }catch(NullPointerException e){logger.warn("null pointer problem (no ref?) with "+osb);}
1040
                }
1041
            }
1042

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

    
1078
                    }
1079
                }
1080
            }
1081
        }else {
1082
            if(sourceNotLinkedToElement(indAssociation,ref,null)) {
1083
                indAssociation.addSource(OriginalSourceType.Import,null, null, ref, null);
1084
            }
1085
                if(sourceNotLinkedToElement(derivedUnitBase, ref,null)) {
1086
                    derivedUnitBase.addSource(OriginalSourceType.Import,null, null, ref, null);
1087
                }
1088
            for (Reference<?> citation : determinationEvent.getReferences()) {
1089
                if(sourceNotLinkedToElement(indAssociation,citation,null))
1090
                 {
1091
                    indAssociation.addSource(DescriptionElementSource.NewInstance(OriginalSourceType.Import, null, null, citation, null));
1092
                }
1093
                    if(sourceNotLinkedToElement(derivedUnitBase, ref,null)) {
1094
                        derivedUnitBase.addSource(OriginalSourceType.Import,null, null, ref, null);
1095
                    }
1096
            }
1097
        }
1098

    
1099
        taxonDescription.addElement(indAssociation);
1100
        taxonDescription.setTaxon(taxon);
1101

    
1102
        save(taxonDescription, state);
1103
        save(taxon, state);
1104
    }
1105

    
1106

    
1107

    
1108
    /**
1109
     * @param derivedUnitBase2
1110
     * @param ref2
1111
     * @param object
1112
     * @return
1113
     */
1114
    private boolean sourceNotLinkedToElement(DerivedUnit derivedUnitBase2, Reference<?> b, String d) {
1115
        Set<IdentifiableSource> linkedSources = derivedUnitBase2.getSources();
1116
        for (IdentifiableSource is:linkedSources){
1117
            Reference a = is.getCitation();
1118
            String c = is.getCitationMicroReference();
1119

    
1120
            boolean refMatch=false;
1121
            boolean microMatch=false;
1122

    
1123
            try{
1124
                if (a==null && b==null) {
1125
                    refMatch=true;
1126
                }
1127
                if (a!=null && b!=null) {
1128
                    if (a.getTitleCache().equalsIgnoreCase(b.getTitleCache())) {
1129
                        refMatch=true;
1130
                    }
1131
                }
1132
            }catch(Exception e){}
1133

    
1134

    
1135
            try{
1136
                if (c==null && d==null) {
1137
                    microMatch=true;
1138
                }
1139
                if(c!=null && d!=null) {
1140
                    if(c.equalsIgnoreCase(d)) {
1141
                        microMatch=true;
1142
                    }
1143
                }
1144
            }
1145
            catch(Exception e){}
1146

    
1147
            if (microMatch && refMatch) {
1148
                return false;
1149
            }
1150

    
1151

    
1152
        }
1153
        return true;
1154
    }
1155

    
1156
    /**
1157
     * @param derivedUnitBase2
1158
     * @param source
1159
     * @return
1160
     */
1161
    private boolean sourceNotLinkedToElement(DerivedUnit derivedUnitBase2, OriginalSourceBase<?> source) {
1162
        Set<IdentifiableSource> linkedSources = derivedUnitBase2.getSources();
1163
        for (IdentifiableSource is:linkedSources){
1164
            Reference a = is.getCitation();
1165
            Reference b = source.getCitation();
1166
            String c = is.getCitationMicroReference();
1167
            String d = source.getCitationMicroReference();
1168

    
1169
            boolean refMatch=false;
1170
            boolean microMatch=false;
1171

    
1172
            try{
1173
                if (a==null && b==null) {
1174
                    refMatch=true;
1175
                }
1176
                if (a!=null && b!=null) {
1177
                    if (a.getTitleCache().equalsIgnoreCase(b.getTitleCache())) {
1178
                        refMatch=true;
1179
                    }
1180
                }
1181
            }catch(Exception e){}
1182

    
1183

    
1184
            try{
1185
                if (c==null && d==null) {
1186
                    microMatch=true;
1187
                }
1188
                if(c!=null && d!=null) {
1189
                    if(c.equalsIgnoreCase(d)) {
1190
                        microMatch=true;
1191
                    }
1192
                }
1193
            }
1194
            catch(Exception e){}
1195

    
1196
            if (microMatch && refMatch) {
1197
                return false;
1198
            }
1199

    
1200

    
1201
        }
1202
        return true;
1203
    }
1204

    
1205
    /**
1206
     * @param indAssociation
1207
     * @param ref2
1208
     * @param object
1209
     * @return
1210
     */
1211
    private boolean sourceNotLinkedToElement(IndividualsAssociation indAssociation, Reference<?> a, String d) {
1212
        Set<DescriptionElementSource> linkedSources = indAssociation.getSources();
1213
        for (DescriptionElementSource is:linkedSources){
1214
            Reference b = is.getCitation();
1215
            String c = is.getCitationMicroReference();
1216

    
1217
            boolean refMatch=false;
1218
            boolean microMatch=false;
1219

    
1220
            try{
1221
                if (a==null && b==null) {
1222
                    refMatch=true;
1223
                }
1224
                if (a!=null && b!=null) {
1225
                    if (a.getTitleCache().equalsIgnoreCase(b.getTitleCache())) {
1226
                        refMatch=true;
1227
                    }
1228
                }
1229
            }catch(Exception e){}
1230

    
1231

    
1232
            try{
1233
                if (c==null && d==null) {
1234
                    microMatch=true;
1235
                }
1236
                if(c!=null && d!=null) {
1237
                    if(c.equalsIgnoreCase(d)) {
1238
                        microMatch=true;
1239
                    }
1240
                }
1241
            }
1242
            catch(Exception e){}
1243

    
1244
            if (microMatch && refMatch) {
1245
                return false;
1246
            }
1247
        }
1248
        return true;
1249
    }
1250

    
1251
    /**
1252
     * @param taxonDescription
1253
     * @param ref2
1254
     * @param object
1255
     * @return
1256
     */
1257
    private boolean sourceNotLinkedToElement(TaxonDescription taxonDescription, Reference<?> a, String d) {
1258
        Set<IdentifiableSource> linkedSources = taxonDescription.getSources();
1259
        for (IdentifiableSource is:linkedSources){
1260
            Reference b = is.getCitation();
1261
            String c = is.getCitationMicroReference();
1262

    
1263
            boolean refMatch=false;
1264
            boolean microMatch=false;
1265

    
1266
            try{
1267
                if (a==null && b==null) {
1268
                    refMatch=true;
1269
                }
1270
                if (a!=null && b!=null) {
1271
                    if (a.getTitleCache().equalsIgnoreCase(b.getTitleCache())) {
1272
                        refMatch=true;
1273
                    }
1274
                }
1275
            }catch(Exception e){}
1276

    
1277

    
1278
            try{
1279
                if (c==null && d==null) {
1280
                    microMatch=true;
1281
                }
1282
                if(c!=null && d!=null) {
1283
                    if(c.equalsIgnoreCase(d)) {
1284
                        microMatch=true;
1285
                    }
1286
                }
1287
            }
1288
            catch(Exception e){}
1289

    
1290
            if (microMatch && refMatch) {
1291
                return false;
1292
            }
1293
        }
1294
        return true;
1295
    }
1296

    
1297
    /**
1298
     * @param indAssociation
1299
     * @param source
1300
     * @return
1301
     */
1302
    private boolean sourceNotLinkedToElement(IndividualsAssociation indAssociation, OriginalSourceBase<?> source) {
1303
        Set<DescriptionElementSource> linkedSources = indAssociation.getSources();
1304
        for (DescriptionElementSource is:linkedSources){
1305
            Reference a = is.getCitation();
1306
            Reference b = source.getCitation();
1307
            String c = is.getCitationMicroReference();
1308
            String d = source.getCitationMicroReference();
1309

    
1310
            boolean refMatch=false;
1311
            boolean microMatch=false;
1312

    
1313
            try{
1314
                if (a==null && b==null) {
1315
                    refMatch=true;
1316
                }
1317
                if (a!=null && b!=null) {
1318
                    if (a.getTitleCache().equalsIgnoreCase(b.getTitleCache())) {
1319
                        refMatch=true;
1320
                    }
1321
                }
1322
            }catch(Exception e){}
1323

    
1324

    
1325
            try{
1326
                if (c==null && d==null) {
1327
                    microMatch=true;
1328
                }
1329
                if(c!=null && d!=null) {
1330
                    if(c.equalsIgnoreCase(d)) {
1331
                        microMatch=true;
1332
                    }
1333
                }
1334
            }
1335
            catch(Exception e){}
1336

    
1337
            if (microMatch && refMatch) {
1338
                return false;
1339
            }
1340
        }
1341
        return true;
1342
    }
1343

    
1344
    /**
1345
     * @param taxonDescription
1346
     * @param sour
1347
     * @return
1348
     */
1349
    private boolean sourceNotLinkedToElement(TaxonDescription taxonDescription, OriginalSourceBase<?> sour) {
1350
        Set<IdentifiableSource> linkedSources = taxonDescription.getSources();
1351
        for (IdentifiableSource is:linkedSources){
1352
            Reference a = is.getCitation();
1353
            Reference b = sour.getCitation();
1354
            String c = is.getCitationMicroReference();
1355
            String d = sour.getCitationMicroReference();
1356

    
1357
            boolean refMatch=false;
1358
            boolean microMatch=false;
1359

    
1360
            try{
1361
                if (a==null && b==null) {
1362
                    refMatch=true;
1363
                }
1364
                if (a!=null && b!=null) {
1365
                    if (a.getTitleCache().equalsIgnoreCase(b.getTitleCache())) {
1366
                        refMatch=true;
1367
                    }
1368
                }
1369
            }catch(Exception e){}
1370

    
1371

    
1372
            try{
1373
                if (c==null && d==null) {
1374
                    microMatch=true;
1375
                }
1376
                if(c!=null && d!=null) {
1377
                    if(c.equalsIgnoreCase(d)) {
1378
                        microMatch=true;
1379
                    }
1380
                }
1381
            }
1382
            catch(Exception e){}
1383

    
1384
            if (microMatch && refMatch) {
1385
                return false;
1386
            }
1387

    
1388

    
1389
        }
1390
        return true;
1391
    }
1392

    
1393
    /**
1394
     * look for the Feature object (FieldObs, Specimen,...)
1395
     * @param unit : a specimen or obersvation base
1396
     * @return the corresponding Feature
1397
     */
1398
    private Feature makeFeature(SpecimenOrObservationBase<?> unit) {
1399
        SpecimenOrObservationType type = unit.getRecordBasis();
1400
        if (type.isFeatureObservation()){
1401
            return Feature.OBSERVATION();
1402
        }else if (type.isFeatureSpecimen()){
1403
            return Feature.SPECIMEN();
1404
        }else if (type == SpecimenOrObservationType.DerivedUnit){
1405
            return Feature.INDIVIDUALS_ASSOCIATION();
1406
        }else{
1407
            String message = "Unhandled record basis '%s' for defining individuals association feature type. Use default.";
1408
            logger.warn(String.format(message, type.getMessage()));
1409
            return Feature.INDIVIDUALS_ASSOCIATION();
1410
        }
1411
    }
1412

    
1413
    /**
1414
     *  getTaxon : search for an existing taxon in the database
1415
     * @param state : the ABCD import state
1416
     * @param scientificName : the name (string)
1417
     * @param i : the current unit position in the abcd file
1418
     * @param rank : the rank for the taxon
1419
     * @return a Taxon
1420
     */
1421
    @SuppressWarnings("rawtypes")
1422
    private Taxon getTaxon(Abcd206ImportState state, String scientificName, int i, Rank rank) {
1423
        System.out.println("GETTAXON "+scientificName);
1424
        Abcd206ImportConfigurator config = state.getConfig();
1425
        Taxon taxon = null;
1426
        NonViralName<?> taxonName = null;
1427

    
1428
        SpecimenUserInteraction sui = state.getConfig().getSpecimenUserInteraction();
1429

    
1430
        System.out.println("config.isReuseExistingTaxaWhenPossible() :"+config.isReuseExistingTaxaWhenPossible());
1431
        if (config.isReuseExistingTaxaWhenPossible()){
1432
            List<TaxonBase> c = null;
1433
            try {
1434
                List<TaxonBase> taxonbaseList = getTaxonService().listByTitle(Taxon.class, scientificName+" sec", MatchMode.BEGINNING, null, null, null, null, null);
1435
                if (taxonbaseList.size()>0){
1436
                    if(config.isInteractWithUser() && config.isAllowReuseOtherClassifications()){
1437
                        taxon = sui.askWhereToFixData(scientificName,taxonbaseList, classification);
1438
                    } else {
1439
                        taxon = sui.lookForTaxaIntoCurrentClassification(taxonbaseList, classification);
1440
                    }
1441
                }
1442
                else{
1443
                    c = getTaxonService().searchTaxaByName(scientificName, ref);
1444
                    if(config.isInteractWithUser() && config.isAllowReuseOtherClassifications()){
1445
                        taxon = sui.askWhereToFixData(scientificName,c, classification);
1446
                    }
1447
                    else{
1448
                        taxon = sui.lookForTaxaIntoCurrentClassification(c, classification);
1449
                    }
1450
                }
1451
            } catch (Exception e) {
1452
                logger.info("Searchtaxabyname failed" + e);
1453
                taxon = null;
1454
            }
1455
        }
1456
        if (!config.isReuseExistingTaxaWhenPossible() || taxon == null){
1457
            System.out.println("create new taxonName instance "+i+", "+config.isParseNameAutomatically());
1458
            if (config.isParseNameAutomatically()){
1459
                taxonName = parseScientificName(scientificName);
1460
            }
1461
            else{
1462
                if (i>=0 && (dataHolder.atomisedIdentificationList != null || dataHolder.atomisedIdentificationList.size() > 0)) {
1463
                    taxonName = setTaxonNameByType(dataHolder.atomisedIdentificationList.get(i), scientificName);
1464
                } else {
1465
                    taxonName=null;
1466
                }
1467
            }
1468
            //            if (taxonName != null) {
1469
            //                System.out.println(taxonName.getTitleCache());
1470
            //            } else {
1471
            //                System.out.println("taxonname: "+taxonName);
1472
            //            }
1473
            if(taxonName == null){
1474
                taxonName = NonViralName.NewInstance(rank);
1475
                taxonName.setFullTitleCache(scientificName,true);
1476
                taxonName.setTitleCache(scientificName, true);
1477
            }
1478
            System.out.println("ADD NEW TAXON *"+taxonName.getRank()+"*"+taxonName.getTitleCache());
1479
            if (rank != null && (taxonName.getRank() ==null || taxonName.getRank().toString().trim().isEmpty())) {
1480
                taxonName.setRank(rank);
1481
            }
1482
            save(taxonName, state);
1483
            taxon = Taxon.NewInstance(taxonName, ref); //sec set null
1484
            save(taxon, state);
1485
        }
1486
        return taxon;
1487
    }
1488

    
1489

    
1490

    
1491

    
1492

    
1493

    
1494

    
1495
    /**
1496
     * HandleIdentifications : get the scientific names present in the ABCD
1497
     * document and store link them with the observation/specimen data
1498
     * @param state: the current ABCD import state
1499
     * @param derivedUnitFacade : the current derivedunitfacade
1500
     */
1501
    private void handleIdentifications(Abcd206ImportState state, DerivedUnitFacade derivedUnitFacade) {
1502
        System.out.println("The reference from handleidentification "+ref);
1503
        Abcd206ImportConfigurator config = state.getConfig();
1504

    
1505
        String fullScientificNameString;
1506
        Taxon taxon = null;
1507
        Rank.GENUS();
1508
        Rank.FAMILY();
1509

    
1510
        String scientificName = "";
1511
        boolean preferredFlag = false;
1512

    
1513
        List<String> scientificNames = new ArrayList<String>();
1514
        if (dataHolder.nomenclatureCode == ""){
1515
            dataHolder.nomenclatureCode = config.getNomenclaturalCode().toString();
1516
        }
1517

    
1518
        for (int i = 0; i < dataHolder.identificationList.size(); i++) {
1519

    
1520
            fullScientificNameString = dataHolder.identificationList.get(i);
1521
            fullScientificNameString = fullScientificNameString.replaceAll(" et ", " & ");
1522

    
1523
            if (fullScientificNameString.indexOf(PREFERRED) != -1) {
1524
                scientificName = fullScientificNameString.split(PREFERRED)[0];
1525
                String pTmp = fullScientificNameString.split(PREFERRED)[1].split(CODE)[0];
1526
                if (pTmp.equals("1") || pTmp.toLowerCase().indexOf("true") != -1) {
1527
                    preferredFlag = true;
1528
                }
1529
                else {
1530
                    preferredFlag = false;
1531
                }
1532
            }
1533
            else {
1534
                scientificName = fullScientificNameString;
1535
            }
1536
            if(DEBUG) {
1537
                logger.info("fullscientificname " + fullScientificNameString + ", *" + dataHolder.nomenclatureCode + "*");
1538
            }
1539
            if (fullScientificNameString.indexOf(CODE) != -1) {
1540
                if (fullScientificNameString.indexOf(':') != -1) {
1541
                    dataHolder.nomenclatureCode = fullScientificNameString.split(CODE)[1].split(COLON)[1];
1542
                }
1543
                else{
1544
                    dataHolder.nomenclatureCode = fullScientificNameString.split(CODE)[1];
1545
                }
1546
            }
1547
            scientificNames.add(scientificName+SPLITTER+preferredFlag+SPLITTER+i);
1548
        }
1549
        for (String name:scientificNames) {
1550
            scientificName = name.split(SPLITTER)[0];
1551
            String pref = name.split(SPLITTER)[1];
1552
            String index = name.split(SPLITTER)[2];
1553
            if (pref.equalsIgnoreCase("true") || scientificNames.size()==1) {
1554
                preferredFlag = true;
1555
            } else {
1556
                preferredFlag =false;
1557
            }
1558
            taxon = getTaxon(state, scientificName,Integer.parseInt(index),null);
1559
            addTaxonNode(taxon, state,preferredFlag);
1560
            linkDeterminationEvent(state, taxon, preferredFlag, derivedUnitFacade);
1561
        }
1562
    }
1563

    
1564
    /**
1565
     * @param taxon : a taxon to add as a node
1566
     * @param state : the ABCD import state
1567
     */
1568
    private void addTaxonNode(Taxon taxon, Abcd206ImportState state, boolean preferredFlag) {
1569
        logger.info("link taxon to a taxonNode "+taxon.getTitleCache());
1570
        boolean exist = false;
1571
        for (TaxonNode p : classification.getAllNodes()){
1572
            try{
1573
                if(p.getTaxon().equals(taxon)) {
1574
                    exist =true;
1575
                }
1576
            }catch(Exception e){logger.warn("TaxonNode does'nt seem to have a taxon");}
1577
        }
1578
        if (!exist){
1579
            addParentTaxon(taxon, state, preferredFlag);
1580
        }
1581
    }
1582

    
1583
    /**
1584
     * Add the hierarchy for a Taxon(add higher taxa)
1585
     * @param taxon: a taxon to add as a node
1586
     * @param state: the ABCD import state
1587
     */
1588
    private void addParentTaxon(Taxon taxon, Abcd206ImportState state, boolean preferredFlag){
1589
        System.out.println("addParentTaxon " + taxon.getTitleCache());
1590

    
1591
        NonViralName<?>  nvname = CdmBase.deproxy(taxon.getName(), NonViralName.class);
1592
        Rank rank = nvname.getRank();
1593
        Taxon genus =null;
1594
        Taxon subgenus =null;
1595
        Taxon species = null;
1596
        Taxon subspecies = null;
1597
        Taxon parent = null;
1598
        if (rank.isLower(Rank.GENUS() )){
1599
            String prefix = nvname.getGenusOrUninomial();
1600
            genus = getTaxon(state, prefix, -1, Rank.GENUS());
1601
            if (preferredFlag) {
1602
                parent = saveOrUpdateClassification(null, genus, state);
1603
            }
1604

    
1605
        }
1606
        if (rank.isLower(Rank.SUBGENUS())){
1607
            String prefix = nvname.getGenusOrUninomial();
1608
            String name = nvname.getInfraGenericEpithet();
1609
            if (name != null){
1610
                subgenus = getTaxon(state, prefix+" "+name, -1, Rank.SUBGENUS());
1611
                if (preferredFlag) {
1612
                    parent = saveOrUpdateClassification(genus, subgenus, state);
1613
                }            }
1614
        }
1615
        if (rank.isLower(Rank.SPECIES())){
1616
            if (subgenus!=null){
1617
                String prefix = nvname.getGenusOrUninomial();
1618
                String name = nvname.getInfraGenericEpithet();
1619
                String spe = nvname.getSpecificEpithet();
1620
                if (spe != null){
1621
                    species = getTaxon(state, prefix+" "+name+" "+spe, -1, Rank.SPECIES());
1622
                    if (preferredFlag) {
1623
                        parent = 	saveOrUpdateClassification(subgenus, species, state);
1624
                    }
1625
                }
1626
            }
1627
            else{
1628
                String prefix = nvname.getGenusOrUninomial();
1629
                String name = nvname.getSpecificEpithet();
1630
                if (name != null){
1631
                    species = getTaxon(state, prefix+" "+name, -1, Rank.SPECIES());
1632
                    if (preferredFlag) {
1633
                        parent = 	saveOrUpdateClassification(genus, species, state);
1634
                    }
1635
                }
1636
            }
1637
        }
1638
        if (rank.isInfraSpecific()){
1639
            subspecies = getTaxon(state, nvname.getFullTitleCache(), -1, Rank.SUBSPECIES());
1640
            if (preferredFlag) {
1641
                parent = 	saveOrUpdateClassification(species, subspecies, state);
1642
            }
1643
        }
1644
        if (preferredFlag) {
1645
            saveOrUpdateClassification(parent, taxon, state);
1646
        }
1647
    }
1648

    
1649
    /**
1650
     * Link a parent to a child and save it in the current classification
1651
     * @param parent: the higher Taxon
1652
     * @param child : the lower (or current) Taxon
1653
     * return the Taxon from the new created Node
1654
     * @param state
1655
     */
1656
    private Taxon saveOrUpdateClassification(Taxon parent, Taxon child, Abcd206ImportState state) {
1657
        System.out.println("ADD CLASSIFICATION parent child "+parent+"," +child);
1658
        TaxonNode node =null;
1659
        if (parent != null) {
1660
            parent = (Taxon) getTaxonService().find(parent.getUuid());
1661
            child = (Taxon) getTaxonService().find(child.getUuid());
1662
            node = classification.addParentChild(parent, child, ref, "");
1663
        }
1664
        if (parent == null) {
1665
            child = (Taxon) getTaxonService().find(child.getUuid());
1666
            node =classification.addChildTaxon(child, ref, null);
1667
        }
1668
        save(classification, state);
1669
        return node.getTaxon();
1670
    }
1671

    
1672
    /**
1673
     * Parse automatically the scientific name
1674
     * @param scientificName: the scientific name to parse
1675
     * @return a parsed name
1676
     */
1677
    private NonViralName<?> parseScientificName(String scientificName) {
1678
        NonViralNameParserImpl nvnpi = NonViralNameParserImpl.NewInstance();
1679
        NonViralName<?> taxonName = null;
1680
        boolean problem = false;
1681

    
1682
        if(DEBUG){
1683
            logger.info("parseScientificName " + dataHolder.nomenclatureCode.toString());
1684
        }
1685

    
1686
        if (dataHolder.nomenclatureCode.toString().equals("Zoological") || dataHolder.nomenclatureCode.toString().contains("ICZN")) {
1687
            taxonName = nvnpi.parseFullName(scientificName, NomenclaturalCode.ICZN, null);
1688
            if (taxonName.hasProblem()) {
1689
                problem = true;
1690
            }
1691
        }
1692
        if (dataHolder.nomenclatureCode.toString().equals("Botanical") || dataHolder.nomenclatureCode.toString().contains("ICBN")) {
1693
            taxonName = nvnpi.parseFullName(scientificName, NomenclaturalCode.ICNAFP, null);
1694
            if (taxonName.hasProblem()) {
1695
                problem = true;
1696
            }
1697
        }
1698
        if (dataHolder.nomenclatureCode.toString().equals("Bacterial") || dataHolder.nomenclatureCode.toString().contains("ICBN")) {
1699
            taxonName = nvnpi.parseFullName(scientificName, NomenclaturalCode.ICNB, null);
1700
            if (taxonName.hasProblem()) {
1701
                problem = true;
1702
            }
1703
        }
1704
        if (dataHolder.nomenclatureCode.toString().equals("Cultivar") || dataHolder.nomenclatureCode.toString().contains("ICNCP")) {
1705
            taxonName = nvnpi.parseFullName(scientificName, NomenclaturalCode.ICNCP, null);
1706
            if (taxonName.hasProblem()) {
1707
                problem = true;
1708
            }
1709
        }
1710
        if (problem) {
1711
            logger.info("Parsing with problem in parseScientificName " + scientificName);
1712
            return null;
1713
        }
1714
        return taxonName;
1715

    
1716
    }
1717

    
1718
    /**
1719
     * Create the name without automatic parsing, either because it failed, or because the user deactivated it.
1720
     * The name is built upon the ABCD fields
1721
     * @param atomisedMap : the ABCD atomised fields
1722
     * @param fullName : the full scientific name
1723
     * @return the corresponding Botanical or Zoological or... name
1724
     */
1725
    private NonViralName<?> setTaxonNameByType(
1726
            HashMap<String, String> atomisedMap, String fullName) {
1727
        boolean problem = false;
1728
        if(DEBUG) {
1729
            logger.info("settaxonnamebytype " + dataHolder.nomenclatureCode.toString());
1730
        }
1731

    
1732
        if (dataHolder.nomenclatureCode.equals("Zoological")) {
1733
            NonViralName<ZoologicalName> taxonName = ZoologicalName.NewInstance(null);
1734
            taxonName.setFullTitleCache(fullName, true);
1735
            taxonName.setGenusOrUninomial(NB(getFromMap(atomisedMap, "Genus")));
1736
            taxonName.setInfraGenericEpithet(NB(getFromMap(atomisedMap, "SubGenus")));
1737
            taxonName.setSpecificEpithet(NB(getFromMap(atomisedMap,"SpeciesEpithet")));
1738
            taxonName.setInfraSpecificEpithet(NB(getFromMap(atomisedMap,"SubspeciesEpithet")));
1739

    
1740
            if (taxonName.getGenusOrUninomial() != null){
1741
                taxonName.setRank(Rank.GENUS());
1742
            }
1743

    
1744
            if (taxonName.getInfraGenericEpithet() != null){
1745
                taxonName.setRank(Rank.SUBGENUS());
1746
            }
1747

    
1748
            if (taxonName.getSpecificEpithet() != null){
1749
                taxonName.setRank(Rank.SPECIES());
1750
            }
1751

    
1752
            if (taxonName.getInfraSpecificEpithet() != null){
1753
                taxonName.setRank(Rank.SUBSPECIES());
1754
            }
1755

    
1756
            Team team = null;
1757
            if (getFromMap(atomisedMap, "AuthorTeamParenthesis") != null) {
1758
                team = Team.NewInstance();
1759
                team.setTitleCache(getFromMap(atomisedMap, "AuthorTeamParenthesis"), true);
1760
            }
1761
            else {
1762
                if (getFromMap(atomisedMap, "AuthorTeamAndYear") != null) {
1763
                    team = Team.NewInstance();
1764
                    team.setTitleCache(getFromMap(atomisedMap, "AuthorTeamAndYear"), true);
1765
                }
1766
            }
1767
            if (team != null) {
1768
                taxonName.setBasionymAuthorTeam(team);
1769
            }
1770
            else {
1771
                if (getFromMap(atomisedMap, "AuthorTeamParenthesis") != null) {
1772
                    taxonName.setAuthorshipCache(getFromMap(atomisedMap, "AuthorTeamParenthesis"));
1773
                }
1774
                else if (getFromMap(atomisedMap, "AuthorTeamAndYear") != null) {
1775
                    taxonName.setAuthorshipCache(getFromMap(atomisedMap, "AuthorTeamAndYear"));
1776
                }
1777
            }
1778
            if (getFromMap(atomisedMap, "CombinationAuthorTeamAndYear") != null) {
1779
                team = Team.NewInstance();
1780
                team.setTitleCache(getFromMap(atomisedMap, "CombinationAuthorTeamAndYear"), true);
1781
                taxonName.setCombinationAuthorTeam(team);
1782
            }
1783
            if (taxonName.hasProblem()) {
1784
                logger.info("pb ICZN");
1785
                problem = true;
1786
            }
1787
            else {
1788
                return taxonName;
1789
            }
1790
        }
1791
        else if (dataHolder.nomenclatureCode.equals("Botanical")) {
1792
            BotanicalName taxonName = (BotanicalName) parseScientificName(fullName);
1793
            if (taxonName != null){
1794
                return taxonName;
1795
            }
1796
            else{
1797
                taxonName = BotanicalName.NewInstance(null);
1798
            }
1799
            taxonName.setFullTitleCache(fullName, true);
1800
            taxonName.setGenusOrUninomial(NB(getFromMap(atomisedMap, "Genus")));
1801
            taxonName.setInfraGenericEpithet(NB(getFromMap(atomisedMap, "FirstEpithet")));
1802
            taxonName.setInfraSpecificEpithet(NB(getFromMap(atomisedMap, "InfraSpeEpithet")));
1803
            try {
1804
                taxonName.setRank(Rank.getRankByName(getFromMap(atomisedMap, "Rank")));
1805
            } catch (Exception e) {
1806
                if (taxonName.getGenusOrUninomial() != null){
1807
                    taxonName.setRank(Rank.GENUS());
1808
                }
1809
                else if (taxonName.getInfraGenericEpithet() != null){
1810
                    taxonName.setRank(Rank.SUBGENUS());
1811
                }
1812
                else if (taxonName.getSpecificEpithet() != null){
1813
                    taxonName.setRank(Rank.SPECIES());
1814
                }
1815
                else if (taxonName.getInfraSpecificEpithet() != null){
1816
                    taxonName.setRank(Rank.SUBSPECIES());
1817
                }
1818
            }
1819
            Team team = null;
1820
            if (getFromMap(atomisedMap, "AuthorTeamParenthesis") != null) {
1821
                team = Team.NewInstance();
1822
                team.setTitleCache(getFromMap(atomisedMap, "AuthorTeamParenthesis"), true);
1823
                taxonName.setBasionymAuthorTeam(team);
1824
            }
1825
            if (getFromMap(atomisedMap, "AuthorTeam") != null) {
1826
                team = Team.NewInstance();
1827
                team.setTitleCache(getFromMap(atomisedMap, "AuthorTeam"), true);
1828
                taxonName.setCombinationAuthorTeam(team);
1829
            }
1830
            if (team == null) {
1831
                if (getFromMap(atomisedMap, "AuthorTeamParenthesis") != null) {
1832
                    taxonName.setAuthorshipCache(getFromMap(atomisedMap, "AuthorTeamParenthesis"));
1833
                }
1834
                else if (getFromMap(atomisedMap, "AuthorTeam") != null) {
1835
                    taxonName.setAuthorshipCache(getFromMap(atomisedMap, "AuthorTeam"));
1836
                }
1837
            }
1838
            if (getFromMap(atomisedMap, "CombinationAuthorTeamAndYear") != null) {
1839
                team = Team.NewInstance();
1840
                team.setTitleCache(getFromMap(atomisedMap, "CombinationAuthorTeamAndYear"), true);
1841
                taxonName.setCombinationAuthorTeam(team);
1842
            }
1843
            if (taxonName.hasProblem()) {
1844
                logger.info("pb ICBN");
1845
                problem = true;
1846
            }
1847
            else {
1848
                return taxonName;
1849
            }
1850
        }
1851
        else if (dataHolder.nomenclatureCode.equals("Bacterial")) {
1852
            NonViralName<BacterialName> taxonName = BacterialName.NewInstance(null);
1853
            taxonName.setFullTitleCache(fullName, true);
1854
            taxonName.setGenusOrUninomial(getFromMap(atomisedMap, "Genus"));
1855
            taxonName.setInfraGenericEpithet(NB(getFromMap(atomisedMap, "SubGenus")));
1856
            taxonName.setSpecificEpithet(NB(getFromMap(atomisedMap, "Species")));
1857
            taxonName.setInfraSpecificEpithet(NB(getFromMap(atomisedMap, "SubspeciesEpithet")));
1858

    
1859
            if (taxonName.getGenusOrUninomial() != null){
1860
                taxonName.setRank(Rank.GENUS());
1861
            }
1862
            else if (taxonName.getInfraGenericEpithet() != null){
1863
                taxonName.setRank(Rank.SUBGENUS());
1864
            }
1865
            else if (taxonName.getSpecificEpithet() != null){
1866
                taxonName.setRank(Rank.SPECIES());
1867
            }
1868
            else if (taxonName.getInfraSpecificEpithet() != null){
1869
                taxonName.setRank(Rank.SUBSPECIES());
1870
            }
1871

    
1872
            if (getFromMap(atomisedMap, "AuthorTeamAndYear") != null) {
1873
                Team team = Team.NewInstance();
1874
                team.setTitleCache(getFromMap(atomisedMap, "AuthorTeamAndYear"), true);
1875
                taxonName.setCombinationAuthorTeam(team);
1876
            }
1877
            if (getFromMap(atomisedMap, "ParentheticalAuthorTeamAndYear") != null) {
1878
                Team team = Team.NewInstance();
1879
                team.setTitleCache(getFromMap(atomisedMap, "ParentheticalAuthorTeamAndYear"), true);
1880
                taxonName.setBasionymAuthorTeam(team);
1881
            }
1882
            if (taxonName.hasProblem()) {
1883
                logger.info("pb ICNB");
1884
                problem = true;
1885
            }
1886
            else {
1887
                return taxonName;
1888
            }
1889
        }
1890
        else if (dataHolder.nomenclatureCode.equals("Cultivar")) {
1891
            CultivarPlantName taxonName = CultivarPlantName.NewInstance(null);
1892

    
1893
            if (taxonName.hasProblem()) {
1894
                logger.info("pb ICNCP");
1895
                problem = true;
1896
            }
1897
            else {
1898
                return taxonName;
1899
            }
1900
            return taxonName;
1901
        }
1902

    
1903
        if (problem) {
1904
            logger.info("Problem im setTaxonNameByType ");
1905
            NonViralName<?> taxonName = NonViralName.NewInstance(null);
1906
            taxonName.setFullTitleCache(fullName, true);
1907
            return taxonName;
1908
        }
1909
        NonViralName<?> tn = NonViralName.NewInstance(null);
1910
        return tn;
1911
    }
1912

    
1913

    
1914
    /**
1915
     * Get a formated string from a hashmap
1916
     * @param atomisedMap
1917
     * @param key
1918
     * @return
1919
     */
1920
    private String getFromMap(HashMap<String, String> atomisedMap, String key) {
1921
        String value = null;
1922
        if (atomisedMap.containsKey(key)) {
1923
            value = atomisedMap.get(key);
1924
        }
1925

    
1926
        try {
1927
            if (value != null && key.matches(".*Year.*")) {
1928
                value = value.trim();
1929
                if (value.matches("[a-z A-Z ]*[0-9]{4}$")) {
1930
                    String tmp = value.split("[0-9]{4}$")[0];
1931
                    int year = Integer.parseInt(value.split(tmp)[1]);
1932
                    if (year >= 1752) {
1933
                        value = tmp;
1934
                    }
1935
                    else {
1936
                        value = null;
1937
                    }
1938
                }
1939
                else {
1940
                    value = null;
1941
                }
1942
            }
1943
        }
1944
        catch (Exception e) {
1945
            value = null;
1946
        }
1947
        return value;
1948
    }
1949

    
1950
    //    private void compareABCDtoCDM(URI urlFileName, List<String> knownElts, Abcd206XMLFieldGetter abcdFieldGetter) {
1951
    //        try {
1952
    //            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
1953
    //            DocumentBuilder constructeur = factory.newDocumentBuilder();
1954
    //            URL url = urlFileName.toURL();
1955
    //            Object o = url.getContent();
1956
    //            InputStream is = (InputStream) o;
1957
    //            Document document = constructeur.parse(is);
1958
    //            Element root = document.getDocumentElement();
1959
    //            abcdFieldGetter.traverse(root);
1960
    //        }
1961
    //        catch (ParserConfigurationException e){
1962
    //            e.printStackTrace();
1963
    //        }
1964
    //        catch (SAXException e) {
1965
    //            e.printStackTrace();
1966
    //        }
1967
    //        catch (IOException e) {
1968
    //            e.printStackTrace();
1969
    //        }
1970
    //        Set<String> elts = dataHolder.allABCDelements.keySet();
1971
    //        Iterator<String> it = elts.iterator();
1972
    //        String elt;
1973
    //        while (it.hasNext()) {
1974
    //            elt = it.next();
1975
    //            if (knownElts.indexOf(elt) == -1) {
1976
    //                if(DEBUG) {
1977
    //                    logger.info("Unmerged ABCD element: " + elt + " - "+ dataHolder.allABCDelements.get(elt));
1978
    //                }
1979
    //            }
1980
    //        }
1981
    //    }
1982

    
1983
    /**
1984
     * Load the list of names from the ABCD file and save them
1985
     * @param state : the current ABCD import state
1986
     * @param unitsList : the unit list from the ABCD file
1987
     * @param abcdFieldGetter : the ABCD parser
1988
     */
1989
    private void prepareCollectors(Abcd206ImportState state, NodeList unitsList, Abcd206XMLFieldGetter abcdFieldGetter) {
1990
        List<String> collectors = new ArrayList<String>();
1991
        List<String> teams = new ArrayList<String>();
1992
        List<List<String>> collectorinteams = new ArrayList<List<String>>();
1993

    
1994
        for (int i = 0; i < unitsList.getLength(); i++) {
1995
            this.getCollectorsFromXML((Element) unitsList.item(i), abcdFieldGetter);
1996
            for (String agent : dataHolder.gatheringAgentList) {
1997
                collectors.add(agent);
1998
            }
1999
            List<String> tmpTeam = new ArrayList<String>(new HashSet<String>(dataHolder.gatheringTeamList));
2000
            if(!tmpTeam.isEmpty()) {
2001
                teams.add(StringUtils.join(tmpTeam.toArray()," & "));
2002
            }
2003
            for (String agent:tmpTeam) {
2004
                collectors.add(agent);
2005
            }
2006
        }
2007

    
2008
        List<String> collectorsU = new ArrayList<String>(new HashSet<String>(collectors));
2009
        List<String> teamsU = new ArrayList<String>(new HashSet<String>(teams));
2010

    
2011

    
2012
        //existing teams in DB
2013
        Map<String,Team> titleCacheTeam = new HashMap<String, Team>();
2014
        List<UuidAndTitleCache<Team>> hiberTeam = getAgentService().getTeamUuidAndTitleCache();
2015

    
2016
        Set<UUID> uuids = new HashSet<UUID>();
2017
        for (UuidAndTitleCache<Team> hibernateT:hiberTeam){
2018
            uuids.add(hibernateT.getUuid());
2019
        }
2020
        if (!uuids.isEmpty()){
2021
            List<AgentBase> existingTeams = getAgentService().find(uuids);
2022
            for (AgentBase<?> existingP:existingTeams){
2023
                titleCacheTeam.put(existingP.getTitleCache(),CdmBase.deproxy(existingP,Team.class));
2024
            }
2025
        }
2026

    
2027

    
2028
        Map<String,UUID> teamMap = new HashMap<String, UUID>();
2029
        for (UuidAndTitleCache<Team> uuidt:hiberTeam){
2030
            teamMap.put(uuidt.getTitleCache(), uuidt.getUuid());
2031
        }
2032

    
2033
        //existing persons in DB
2034
        List<UuidAndTitleCache<Person>> hiberPersons = getAgentService().getPersonUuidAndTitleCache();
2035
        Map<String,Person> titleCachePerson = new HashMap<String, Person>();
2036
        uuids = new HashSet<UUID>();
2037
        for (UuidAndTitleCache<Person> hibernateP:hiberPersons){
2038
            uuids.add(hibernateP.getUuid());
2039
        }
2040

    
2041
        if (!uuids.isEmpty()){
2042
            List<AgentBase> existingPersons = getAgentService().find(uuids);
2043
            for (AgentBase<?> existingP:existingPersons){
2044
                titleCachePerson.put(existingP.getTitleCache(),CdmBase.deproxy(existingP,Person.class));
2045
            }
2046
        }
2047

    
2048
        Map<String,UUID> personMap = new HashMap<String, UUID>();
2049
        for (UuidAndTitleCache<Person> person:hiberPersons){
2050
            personMap.put(person.getTitleCache(), person.getUuid());
2051
        }
2052

    
2053
        java.util.Collection<Person> personToadd = new ArrayList<Person>();
2054
        java.util.Collection<Team> teamToAdd = new ArrayList<Team>();
2055

    
2056
        for (String collector:collectorsU){
2057
            Person p = Person.NewInstance();
2058
            p.setTitleCache(collector,true);
2059
            if (!personMap.containsKey(p.getTitleCache())){
2060
                personToadd.add(p);
2061
            }
2062
        }
2063
        for (String team:teamsU){
2064
            Team p = Team.NewInstance();
2065
            p.setTitleCache(team,true);
2066
            if (!teamMap.containsKey(p.getTitleCache())){
2067
                teamToAdd.add(p);
2068
            }
2069
        }
2070

    
2071
        if(!personToadd.isEmpty()){
2072
            for (Person agent: personToadd){
2073
                save(agent, state);
2074
                titleCachePerson.put(agent.getTitleCache(),CdmBase.deproxy(agent, Person.class) );
2075
            }
2076
        }
2077

    
2078
        Person ptmp ;
2079
        Map <String,Integer>teamdone = new HashMap<String, Integer>();
2080
        for (List<String> collteam: collectorinteams){
2081
            if (!teamdone.containsKey(StringUtils.join(collteam.toArray(),"-"))){
2082
                Team team = new Team();
2083
                boolean em =true;
2084
                for (String collector:collteam){
2085
                    ptmp = Person.NewInstance();
2086
                    ptmp.setTitleCache(collector,true);
2087
                    Person p2 = titleCachePerson.get(ptmp.getTitleCache());
2088
                    team.addTeamMember(p2);
2089
                    em=false;
2090
                }
2091
                if (!em) {
2092
                    teamToAdd.add(team);
2093
                }
2094
                teamdone.put(StringUtils.join(collteam.toArray(),"-"),0);
2095
            }
2096
        }
2097

    
2098
        if(!teamToAdd.isEmpty()){
2099
            for (Team agent: teamToAdd){
2100
                save(agent, state);
2101
                titleCacheTeam.put(agent.getTitleCache(), CdmBase.deproxy( agent,Team.class) );
2102
            }
2103
        }
2104

    
2105
        state.getConfig().setTeams(titleCacheTeam);
2106
        state.getConfig().setPersons(titleCachePerson);
2107
    }
2108

    
2109
    @Override
2110
    protected boolean isIgnore(Abcd206ImportState state) {
2111
        return false;
2112
    }
2113

    
2114

    
2115
}
(2-2/5)