Project

General

Profile

Download (43.2 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.excel.in;
11

    
12
import java.io.FileNotFoundException;
13
import java.net.MalformedURLException;
14
import java.net.URI;
15
import java.util.ArrayList;
16
import java.util.Calendar;
17
import java.util.HashMap;
18
import java.util.HashSet;
19
import java.util.List;
20
import java.util.Map;
21
import java.util.Scanner;
22
import java.util.Set;
23
import java.util.UUID;
24

    
25
import org.apache.commons.lang.StringUtils;
26
import org.apache.log4j.Logger;
27
import org.springframework.stereotype.Component;
28
import org.springframework.transaction.TransactionStatus;
29

    
30
import eu.etaxonomy.cdm.api.facade.DerivedUnitFacade;
31
import eu.etaxonomy.cdm.common.ExcelUtils;
32
import eu.etaxonomy.cdm.io.common.CdmImportBase;
33
import eu.etaxonomy.cdm.io.common.ICdmIO;
34
import eu.etaxonomy.cdm.io.specimen.UnitsGatheringArea;
35
import eu.etaxonomy.cdm.io.specimen.UnitsGatheringEvent;
36
import eu.etaxonomy.cdm.model.agent.AgentBase;
37
import eu.etaxonomy.cdm.model.agent.Institution;
38
import eu.etaxonomy.cdm.model.agent.Person;
39
import eu.etaxonomy.cdm.model.agent.Team;
40
import eu.etaxonomy.cdm.model.common.CdmBase;
41
import eu.etaxonomy.cdm.model.common.Language;
42
import eu.etaxonomy.cdm.model.common.OriginalSourceType;
43
import eu.etaxonomy.cdm.model.common.TimePeriod;
44
import eu.etaxonomy.cdm.model.description.DescriptionElementSource;
45
import eu.etaxonomy.cdm.model.description.Feature;
46
import eu.etaxonomy.cdm.model.description.IndividualsAssociation;
47
import eu.etaxonomy.cdm.model.description.TaxonDescription;
48
import eu.etaxonomy.cdm.model.location.NamedArea;
49
import eu.etaxonomy.cdm.model.media.Media;
50
import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
51
import eu.etaxonomy.cdm.model.name.TaxonName;
52
import eu.etaxonomy.cdm.model.name.TaxonNameFactory;
53
import eu.etaxonomy.cdm.model.occurrence.Collection;
54
import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
55
import eu.etaxonomy.cdm.model.occurrence.DeterminationEvent;
56
import eu.etaxonomy.cdm.model.occurrence.GatheringEvent;
57
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
58
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationType;
59
import eu.etaxonomy.cdm.model.reference.Reference;
60
import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
61
import eu.etaxonomy.cdm.model.taxon.Classification;
62
import eu.etaxonomy.cdm.model.taxon.Taxon;
63
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
64
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
65
import eu.etaxonomy.cdm.model.term.DefinedTermBase;
66
import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
67
import eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl;
68
import eu.etaxonomy.cdm.strategy.parser.TimePeriodParser;
69

    
70
/**
71
 * @author p.kelbert
72
 * @since 29.10.2008
73
 * @since 13 mars 2013
74
 *
75
 */
76
@Component
77
public class SpecimenSythesysExcelImport  extends CdmImportBase<SpecimenSynthesysExcelImportConfigurator, SpecimenSynthesysExcelImportState>
78
        implements ICdmIO<SpecimenSynthesysExcelImportState> {
79

    
80
    private static final Logger logger = Logger.getLogger(SpecimenSythesysExcelImport.class);
81

    
82
    protected String fullScientificNameString;
83
    protected String nomenclatureCode;
84
    protected String institutionCode;
85
    protected String collectionCode;
86
    protected String unitID;
87
    protected String recordBasis;
88
    protected String accessionNumber;
89
    protected String fieldNumber;
90
    protected Double longitude;
91
    protected Double latitude;
92
    protected String locality;
93
    protected String languageIso = null;
94
    protected String country;
95
    protected String isocountry;
96
    protected int depth;
97
    protected int altitude;
98
    protected String gatheringYear;
99
    protected String gatheringMonth;
100
    protected String gatheringDay;
101
    protected String gatheringDate;
102
    protected String gatheringTeam;
103
    protected String gatheringAgent;
104
    protected String originalsource;
105
    protected String identifier;
106
    protected String gatheringNotes;
107

    
108
    private DerivedUnit derivedUnitBase;
109
    private Reference ref = null;
110
    private TransactionStatus tx;
111
    private Classification classification = null;
112

    
113
    protected ArrayList<String> identificationList = new ArrayList<String>();
114
    protected ArrayList<String> multimediaObjects = new ArrayList<String>();
115
    private boolean keepAtomisedDate=true;
116
    private boolean useTDWGarea = true;
117

    
118
    boolean DEBUG =false;
119

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

    
124
    /**
125
     * private HashMap that handle null values (missing keys)
126
     * return empty string instead of null
127
     * */
128
    public class MyHashMap<K,V> extends HashMap<K,V> {
129
        /**
130
         *
131
         */
132
        private static final long serialVersionUID = -6230407405666753405L;
133

    
134
        @SuppressWarnings("unchecked")
135
        @Override
136
        public V get(Object key) {
137
            Object a;
138
            if (containsKey(key)) {
139
                a= super.get(key);
140
            } else {
141
                a="";
142
            }
143
            if (a ==null || a.toString().equalsIgnoreCase("none")) {
144
                a="";
145
            }
146
            return (V) a;
147
        }
148
    }
149

    
150

    
151
    /**
152
     * getClassification : get the classification declared in the ImportState
153
     *
154
     * @param state
155
     * @return
156
     */
157
    private void setClassification(SpecimenSynthesysExcelImportState state) {
158
        if (classification == null){
159
            boolean configreused=false;
160
            if (state.getConfig().getClassificationName()!=null && state.getConfig().getClassificationName().equalsIgnoreCase("Goosefoots")) {
161
                classification = getClassificationService().find(UUID.fromString("2c2dc41c-9891-42cd-9cd5-8b28dfdd1b8a"));
162
                if (classification ==null){
163
                    String name = state.getConfig().getClassificationName();
164
                    classification = Classification.NewInstance(name, ref, Language.DEFAULT());
165
                    getClassificationService().saveOrUpdate(classification);
166
                }
167
                configreused=true;
168
            }
169
            if (state.getConfig().getClassificationName()!=null && state.getConfig().getClassificationName().equalsIgnoreCase("Ants")) {
170
                classification = getClassificationService().find(UUID.fromString("9b72d32f-2868-4f0d-81bd-ebc38ee8c645"));
171
                if (classification ==null){
172
                    String name = state.getConfig().getClassificationName();
173
                    classification = Classification.NewInstance(name, ref, Language.DEFAULT());
174
                    getClassificationService().saveOrUpdate(classification);
175
                }
176
                configreused=true;
177
            }
178
            if (state.getConfig().getClassificationName()!=null && state.getConfig().getClassificationName().equalsIgnoreCase("Fungi")) {
179
                classification = getClassificationService().find(UUID.fromString("fe07274d-daff-4678-9f7d-2c3916948c3e"));
180
                if (classification ==null){
181
                    String name = state.getConfig().getClassificationName();
182
                    classification = Classification.NewInstance(name, ref, Language.DEFAULT());
183
                    getClassificationService().saveOrUpdate(classification);
184
                }
185
                configreused=true;
186
            }
187
            if (state.getConfig().getClassificationName()!=null && state.getConfig().getClassificationName().equalsIgnoreCase("Campylopus")) {
188
                classification = getClassificationService().find(UUID.fromString("9dccbd11-eb0e-4cac-ae04-aa61ad82b8a6"));
189
                if (classification ==null){
190
                    String name = state.getConfig().getClassificationName();
191
                    classification = Classification.NewInstance(name, ref, Language.DEFAULT());
192
                    getClassificationService().saveOrUpdate(classification);
193
                }
194
                configreused=true;
195
            }
196

    
197
            if (state.getConfig().getClassificationName()!=null && state.getConfig().getClassificationName().equalsIgnoreCase("Eupolybothrus")) {
198
                classification = getClassificationService().find(UUID.fromString("62ce65e0-e036-49aa-aae7-4d4d0f88966c"));
199
                if (classification ==null){
200
                    String name = state.getConfig().getClassificationName();
201
                    classification = Classification.NewInstance(name, ref, Language.DEFAULT());
202
                    getClassificationService().saveOrUpdate(classification);
203
                }
204
                configreused=true;
205
            }
206
            if(!configreused){
207

    
208
                String name = state.getConfig().getClassificationName();
209
                classification = Classification.NewInstance(name, ref, Language.DEFAULT());
210
                if (state.getConfig().getClassificationUuid() != null) {
211
                    classification.setUuid(state.getConfig().getClassificationUuid());
212
                }
213
                getClassificationService().saveOrUpdate(classification);
214
            }
215

    
216
        }
217
    }
218

    
219
    /**
220
     * refresh the hibernate transaction :
221
     * - commit the current queries
222
     * - get the reference and the classification and the derivedUnitBase back from the hibernate session
223
     * */
224
    private void refreshTransaction(){
225
        commitTransaction(tx);
226
        tx = startTransaction();
227
        ref = getReferenceService().find(ref.getUuid());
228
        classification = getClassificationService().find(classification.getUuid());
229
        try{
230
            derivedUnitBase = (DerivedUnit) getOccurrenceService().find(derivedUnitBase.getUuid());
231
        }catch(Exception e){
232
            //logger.warn("derivedunit up to date or not created yet");
233
        }
234
    }
235

    
236
    //    /**
237
    //     * refresh the hibernate transaction :
238
    //     * - commit the current queries
239
    //     * - get the reference and the classification and the derivedUnitBase back from the hibernate session
240
    //     * */
241
    //    private void refreshTransac(){
242
    //        commitTransaction(tx);
243
    //        tx = startTransaction();
244
    //    }
245
    /*
246
     * Store the unit's properties into variables
247
     * @param unit: the hashmap containing the splitted Excel line (Key=column name, value=value)
248
     */
249
    private void setUnitPropertiesExcel(MyHashMap<String,String> unit, String defaultAuthor){
250
        multimediaObjects = new ArrayList<String>();
251
        identificationList = new ArrayList<String>();
252
        gatheringTeam="";
253
        gatheringAgent="";
254

    
255
        String author = unit.get("author");
256
        if (author.isEmpty() && !defaultAuthor.isEmpty()) {
257
            author=defaultAuthor;
258
        }
259
        String taxonName = unit.get("taxonName");
260

    
261
        institutionCode = unit.get("institution");
262
        collectionCode = unit.get("collection");
263
        unitID = unit.get("unitID");
264
        recordBasis = unit.get("recordBasis");
265

    
266
        accessionNumber = null;
267

    
268
        try {longitude = Double.valueOf(unit.get("longitude"));
269
        } catch (Exception e) {longitude = 0.0;}
270

    
271
        try {latitude = Double.valueOf(unit.get("latitude"));
272
        } catch (Exception e) {latitude = 0.0;}
273

    
274
        country = unit.get("country");
275
        isocountry = unit.get("isoCountry");
276
        locality = unit.get("locality");
277
        String habitat = unit.get("habitat");
278
        String stateProvince = unit.get("stateProvince");
279
        if (!stateProvince.isEmpty()) {
280
            locality=stateProvince+", "+locality;
281
        }
282
        if (!habitat.isEmpty()){
283
            locality+=" (Habitat: "+habitat+")";
284
        }
285

    
286
        fieldNumber = unit.get("field number");
287

    
288
        String url =unit.get("url");
289
        if (!url.isEmpty()) {
290
            multimediaObjects.add(url);
291
        }
292

    
293
        String coll =unit.get("collector");
294
        if (!coll.isEmpty()) {
295
            if (coll.indexOf("& al.")!=-1 || coll.indexOf("et al.") != -1 || coll.indexOf(" al. ")!=-1 ||
296
                    coll.indexOf("&") != -1 || coll.indexOf(" et ") != -1 || coll.indexOf(";")!=-1) {
297
                gatheringTeam = coll;
298
            } else{
299
                //single
300
                gatheringAgent = coll;
301
            }
302
        }
303

    
304
        if(!taxonName.contains(author)) {
305
            identificationList.add(taxonName+" "+author);
306
        } else {
307
            identificationList.add(taxonName);
308
        }
309

    
310
        gatheringYear = unit.get("year");
311
        gatheringMonth = unit.get("month");
312
        gatheringDay = unit.get("day");
313
        gatheringDate = unit.get("date");
314

    
315
        gatheringNotes = unit.get("eventRemarks");
316
        originalsource = unit.get("originalsource");
317
        identifier = unit.get("identifier");
318
    }
319

    
320

    
321
    private Institution getInstitution(SpecimenSynthesysExcelImportConfigurator config){
322
        Institution institution;
323
        List<Institution> institutions;
324
        try{
325
            institutions= getAgentService().searchInstitutionByCode(institutionCode);
326
        }catch(Exception e){
327
            institutions=new ArrayList<Institution>();
328
        }
329
        if (institutions.size() ==0 || !config.getReUseExistingMetadata()){
330
            logger.debug("Institution (agent) unknown or not allowed to reuse existing metadata");
331
            //create institution
332
            institution = Institution.NewInstance();
333
            institution.setCode(institutionCode);
334
            getAgentService().saveOrUpdate(institution);
335
        }
336
        else{
337
            logger.debug("Institution (agent) already in the db");
338
            institution = institutions.get(0);
339
        }
340
        return CdmBase.deproxy(institution, Institution.class);
341
    }
342

    
343
    /*
344
     * Look if the Collection does already exists
345
     * @param collectionCode: a string
346
     * @param institution: the current Institution
347
     * @param app
348
     * @return the Collection (existing or new)
349
     */
350
    private Collection getCollection(Institution institution, SpecimenSynthesysExcelImportConfigurator config){
351
        Collection collection =null;
352
        List<Collection> collections;
353
        try{
354
            collections = getCollectionService().searchByCode(collectionCode);
355
        }catch(Exception e){
356
            collections=new ArrayList<Collection>();
357
        }
358
        if (collections.size() ==0 || !config.getReUseExistingMetadata()){
359
            logger.debug("Collection not found or do not reuse existing metadata  "+collectionCode);
360
            //create new collection
361
            collection= Collection.NewInstance();
362
            collection.setCode(collectionCode);
363
            collection.setCodeStandard("GBIF");
364
            collection.setInstitute(institution);
365
        }
366
        else{
367
            boolean collectionFound=false;
368
            for (int i=0; i<collections.size(); i++){
369
                collection = collections.get(i);
370
                try {
371
                    if (collection.getInstitute().getCode().equalsIgnoreCase(institution.getCode())){
372
                        //found a collection with the same code and the same institution
373
                        collectionFound=true;
374
                    }
375
                } catch (NullPointerException e) {}
376
            }
377
            if (!collectionFound){
378
                collection= Collection.NewInstance();
379
                collection.setCode(collectionCode);
380
                collection.setCodeStandard("GBIF");
381
                collection.setInstitute(institution);
382
            }
383

    
384
        }
385
        return collection;
386
    }
387

    
388
    /*
389
     *
390
     * @param app
391
     * @param derivedThing
392
     * @param sec
393
     */
394
    private void setTaxonName(SpecimenSynthesysExcelImportConfigurator config){
395
        TaxonName taxonName = null;
396
        Taxon taxon = null;
397

    
398
        String scientificName="";
399
        boolean preferredFlag=false;
400

    
401
        for (int i = 0; i < identificationList.size(); i++) {
402
            String fullScientificNameString = identificationList.get(i);
403
            fullScientificNameString = fullScientificNameString.replaceAll(" et ", " & ");
404
            if (fullScientificNameString.indexOf("_preferred_") != -1){
405
                scientificName = fullScientificNameString.split("_preferred_")[0].trim();
406
                String pTmp = fullScientificNameString.split("_preferred_")[1].split("_code_")[0];
407
                if (pTmp == "1" || pTmp.toLowerCase().indexOf("true") != -1) {
408
                    preferredFlag=true;
409
                } else {
410
                    preferredFlag=false;
411
                }
412
            }else {
413
                scientificName = fullScientificNameString.trim();
414
            }
415

    
416
            if (fullScientificNameString.indexOf("_code_") != -1){
417
                nomenclatureCode = fullScientificNameString.split("_code_")[1].trim();
418
            }
419

    
420
            if (config.getDoReUseTaxon()){
421
                List<TaxonBase> c = null;
422
                try {
423
                    Taxon cc= getTaxonService().findBestMatchingTaxon(scientificName);
424
                    if (cc != null){
425
                        if ((cc.getSec() == null || cc.getSec().toString().isEmpty()) || (cc.getSec() != null &&
426
                                cc.getSec().getTitleCache().equalsIgnoreCase(ref.getTitleCache()))) {
427
                            if(cc.getSec() == null || cc.getSec().toString().isEmpty()){
428
                                cc.setSec(ref);
429
                                getTaxonService().saveOrUpdate(cc);
430
                            }
431
                            taxon=cc;
432
                        }
433
                    }
434
                    else{
435
                        c = getTaxonService().searchByName(scientificName, INCLUDE_UNPUBLISHED, ref);
436
                        for (TaxonBase<?> b : c) {
437
                            taxon = (Taxon) b;
438
                        }
439
                    }
440
                } catch (Exception e) {
441
                    logger.info("Searchtaxabyname failed" + e);
442
                    taxon = null;
443
                }
444

    
445
            }
446
            if (!config.getDoReUseTaxon() || taxon == null){
447
                if (DEBUG) {
448
                    logger.info("create new taxonName instance");
449
                }
450
                if (config.getDoAutomaticParsing()){
451
                    taxonName = parseScientificName(scientificName);
452
                }
453
                else{
454
                    taxonName = TaxonNameFactory.NewNonViralInstance(null);
455
                    taxonName.setTitleCache(scientificName, true);
456
                }
457
                getNameService().save(taxonName);
458
                taxon = Taxon.NewInstance(taxonName, ref); //sec set null
459
                getTaxonService().save(taxon);
460
                //   refreshTransaction();
461
                taxon = (Taxon) getTaxonService().find(taxon.getUuid());
462
                taxon = addTaxonNode(taxon, config);
463
            }
464

    
465

    
466

    
467
            DeterminationEvent determinationEvent = DeterminationEvent.NewInstance();
468
            determinationEvent.setTaxon(getTaxonService().find(taxon.getUuid()));
469
            determinationEvent.setPreferredFlag(preferredFlag);
470

    
471
            determinationEvent.setIdentifiedUnit(derivedUnitBase);
472
            if (!identifier.isEmpty()){
473
                Person p = Person.NewInstance();
474
                p.setTitleCache(identifier, true);
475
                determinationEvent.setActor(p);
476
            }
477
            derivedUnitBase.addDetermination(determinationEvent);
478

    
479
            makeIndividualsAssociation(taxon,determinationEvent,config);
480

    
481
            getOccurrenceService().saveOrUpdate(derivedUnitBase);
482
        }
483

    
484
    }
485

    
486
    /**
487
     * @param taxon
488
     * @param taxonName
489
     * @param config
490
     * @return
491
     */
492
    private Taxon addTaxonNode(Taxon taxon, SpecimenSynthesysExcelImportConfigurator config) {
493
        if (DEBUG) {
494
            logger.info("link taxon to a taxonNode");
495
        }
496
        boolean exist = false;
497
        for (TaxonNode p : classification.getAllNodes()){
498
            if(p.getTaxon().equals(taxon)) {
499
                exist =true;
500
            }
501
        }
502
        if (!exist){
503
            taxon = (Taxon) getTaxonService().find(taxon.getUuid());
504
            classification.addChildTaxon(taxon, ref, null);
505
            getClassificationService().saveOrUpdate(classification);
506
            //            refreshTransaction();
507
        }
508
        return (Taxon) getTaxonService().find(taxon.getUuid());
509
    }
510

    
511
    private TaxonName parseScientificName(String scientificName){
512
        if (DEBUG) {
513
            logger.debug("in parseScientificName");
514
        }
515
        NonViralNameParserImpl nvnpi = NonViralNameParserImpl.NewInstance();
516
        TaxonName taxonName = null;
517
        boolean problem=false;
518

    
519
        if (DEBUG) {
520
            logger.debug("nomenclature: "+nomenclatureCode);
521
        }
522

    
523
        if(nomenclatureCode == null){
524
            taxonName = TaxonNameFactory.NewNonViralInstance(null);
525
            taxonName.setTitleCache(scientificName, true);
526
            return taxonName;
527
        }
528

    
529
        if (nomenclatureCode.toString().equals("Zoological")){
530
            taxonName = (TaxonName)nvnpi.parseFullName(scientificName,NomenclaturalCode.ICZN,null);
531
            if (taxonName.hasProblem()) {
532
                problem=true;
533
            }
534
        }
535
        if (nomenclatureCode.toString().equals("Botanical")){
536
            taxonName  = (TaxonName)nvnpi.parseFullName(scientificName,NomenclaturalCode.ICNAFP,null);
537
            if (taxonName.hasProblem()) {
538
                problem=true;
539
            }}
540
        if (nomenclatureCode.toString().equals("Bacterial")){
541
            taxonName = (TaxonName)nvnpi.parseFullName(scientificName,NomenclaturalCode.ICNB, null);
542
            if (taxonName.hasProblem()) {
543
                problem=true;
544
            }
545
        }
546
        if (nomenclatureCode.toString().equals("Cultivar")){
547
            taxonName = (TaxonName)nvnpi.parseFullName(scientificName,NomenclaturalCode.ICNCP, null);
548
            if (taxonName.hasProblem()) {
549
                problem=true;
550
            }
551
        }
552
        //      if (nomenclatureCode.toString().equals("Viral")){
553
        //      ViralName taxonName = (ViralName)nvnpi.parseFullName(scientificName,NomenclaturalCode.ICVCN(), null);
554
        //      if (taxonName.hasProblem())
555
        //      System.out.println("pb ICVCN");
556
        //      }
557
        //TODO: parsing of ViralNames?
558
        if(problem){
559
            taxonName = TaxonNameFactory.NewNonViralInstance(null);
560
            taxonName.setTitleCache(scientificName, true);
561
        }
562
        return taxonName;
563

    
564
    }
565

    
566
    private DerivedUnitFacade getFacade() {
567
        // logger.info("GETFACADE");
568
        /**
569
         * SPECIMEN OR OBSERVATION OR LIVING
570
         */
571
        // DerivedUnit derivedThing = null;
572
        SpecimenOrObservationType type = null;
573

    
574
        // create specimen
575
        if (recordBasis != null) {
576
            String rec = recordBasis.toLowerCase();
577
            if (rec.contains("specimen") || rec.startsWith("s")) {// specimen
578
                type = SpecimenOrObservationType.PreservedSpecimen;
579
            }
580
            if (rec.contains("observat") || rec.startsWith("o")) {
581
                type = SpecimenOrObservationType.Observation;
582
            }
583
            if (rec.contains("fossil") || rec.startsWith("f") ){
584
                type = SpecimenOrObservationType.Fossil;
585
            }
586

    
587
            if (rec.contains("living") || rec.startsWith("l")) {
588
                type = SpecimenOrObservationType.LivingSpecimen;
589
            }
590
            if (type == null) {
591
                if(DEBUG) {
592
                    logger.info("The basis of record does not seem to be known: "   + recordBasis);
593
                }
594
                type = SpecimenOrObservationType.DerivedUnit;
595
            }
596
        } else {
597
            logger.info("The basis of record is null");
598
            type = SpecimenOrObservationType.DerivedUnit;
599
        }
600
        DerivedUnitFacade derivedUnitFacade = DerivedUnitFacade.NewInstance(type);
601
        return derivedUnitFacade;
602
    }
603

    
604
    /*
605
     * Store the unit with it's Gathering informations in the CDM
606
     */
607
    public boolean start(SpecimenSynthesysExcelImportConfigurator config){
608
        boolean result = true;
609

    
610
        //        refreshTransaction();
611
        try {
612

    
613
            /**
614
             * SPECIMEN OR OBSERVATION OR LIVING
615
             */
616
            DerivedUnitFacade derivedUnitFacade = getFacade();
617
            derivedUnitBase = derivedUnitFacade.innerDerivedUnit();
618

    
619
            //set catalogue number (unitID)
620
            derivedUnitFacade.setCatalogNumber(unitID);
621
            derivedUnitFacade.setAccessionNumber(accessionNumber);
622

    
623
            if (!originalsource.isEmpty()){
624
                Reference reference = ReferenceFactory.newGeneric();
625
                reference.setTitleCache(originalsource, true);
626
                derivedUnitBase.addSource(OriginalSourceType.Import, originalsource, "", reference, "");
627
            }else{
628
                derivedUnitBase.addSource(OriginalSourceType.Import, unitID,"",ref,ref.getCitation());
629
            }
630
            /**
631
             * INSTITUTION & COLLECTION
632
             */
633
            //manage institution
634
            if (!institutionCode.isEmpty()){
635
                Institution institution = getInstitution(config);
636
                //manage collection
637
                if (!collectionCode.isEmpty()){
638
                    Collection collection = getCollection(institution, config);
639
                    //link specimen & collection
640
                    derivedUnitFacade.setCollection(collection);
641
                }
642
            }
643

    
644
            /**
645
             * GATHERING EVENT
646
             */
647
            // gathering event
648
            UnitsGatheringEvent unitsGatheringEvent = new UnitsGatheringEvent(getTermService(), locality, languageIso,
649
                    longitude, latitude, gatheringAgent, gatheringTeam,config);
650
            // country
651
            UnitsGatheringArea unitsGatheringArea = new UnitsGatheringArea();
652
            unitsGatheringArea.useTDWGareas(this.useTDWGarea);
653
            //            unitsGatheringArea.setConfig(config, getOccurrenceService(),getTermService());
654
            unitsGatheringArea.setParams(isocountry, country, config, getTermService(), getOccurrenceService(), getVocabularyService());
655
            DefinedTermBase areaCountry =unitsGatheringArea.getCountry();
656

    
657

    
658

    
659
            // copy gathering event to facade
660
            GatheringEvent gatheringEvent = unitsGatheringEvent.getGatheringEvent();
661
            //join gatheringEvent to fieldObservation
662
            derivedUnitFacade.setGatheringEvent(gatheringEvent);
663

    
664
            derivedUnitFacade.setLocality(gatheringEvent.getLocality());
665
            derivedUnitFacade.setExactLocation(gatheringEvent.getExactLocation());
666
            //derivedUnitFacade.setCollector(gatheringEvent.getCollector());
667
            derivedUnitFacade.setCountry((NamedArea)areaCountry);
668
            for(DefinedTermBase<?> area:unitsGatheringArea.getAreas()){
669
                derivedUnitFacade.addCollectingArea((NamedArea) area);
670
            }
671
            if (gatheringNotes != null && !gatheringNotes.isEmpty()) {
672
                derivedUnitFacade.setFieldNotes(gatheringNotes);
673
            }
674

    
675

    
676
            /*
677
             * merge AND STORE DATA
678
             */
679
            //            getTermService().saveOrUpdate(areaCountry);// TODO save area sooner
680
            getTermService().saveLanguageData(unitsGatheringEvent.getLocality());
681

    
682

    
683

    
684
            //add gathering date
685
            if (keepAtomisedDate && (!gatheringYear.isEmpty() || !gatheringMonth.isEmpty() || !gatheringDay.isEmpty())){
686
                Calendar calendar =  Calendar.getInstance();
687
                if (!gatheringYear.isEmpty()) {
688
                    TimePeriod tp = TimePeriod.NewInstance(Integer.parseInt(gatheringYear));
689
                    if (!gatheringMonth.isEmpty()) {
690
                        tp.setStartMonth(Integer.parseInt(gatheringMonth));
691
                        if (!gatheringDay.isEmpty()) {
692
                            tp.setStartDay(Integer.parseInt(gatheringDay));
693
                        }
694
                    }
695
                    unitsGatheringEvent.setGatheringDate(tp);
696
                }
697

    
698
            }else{
699
                if (!gatheringDate.isEmpty()){
700
                    TimePeriod tp = TimePeriodParser.parseString(gatheringDate);
701
                    unitsGatheringEvent.setGatheringDate(tp);
702
                }
703
            }
704

    
705

    
706
            //add fieldNumber
707
            derivedUnitFacade.setFieldNumber(fieldNumber);
708

    
709
            //add Multimedia URLs
710
            if(multimediaObjects.size()>0){
711
                for (String multimediaObject : multimediaObjects) {
712
                    Media media;
713
                    try {
714
                        media = getImageMedia(multimediaObject, READ_MEDIA_DATA);
715
                        derivedUnitFacade.addDerivedUnitMedia(media);
716
                    } catch (MalformedURLException e) {
717
                        // TODO Auto-generated catch block
718
                        e.printStackTrace();
719
                    }
720
                }
721
            }
722

    
723
            getOccurrenceService().saveOrUpdate(derivedUnitBase);
724

    
725
            setTaxonName(config);
726

    
727
            //         refreshTransaction();
728
            if (DEBUG) {
729
                logger.info("saved new specimen ...");
730
            }
731

    
732
        } catch (Exception e) {
733
            logger.warn("Error when reading record!!");
734
            e.printStackTrace();
735
            result = false;
736
        }
737
        if (DEBUG) {
738
            logger.info("commit done");
739
        }
740
        //app.close();
741
        return result;
742
    }
743

    
744
    /*
745
     * Store the unit with it's Gathering informations in the CDM
746
     */
747
    public boolean resetCollectionInstitution(SpecimenSynthesysExcelImportConfigurator config,List<SpecimenOrObservationBase> specimenOrObs){
748
        boolean result = true;
749

    
750

    
751
        for (SpecimenOrObservationBase<?> specimen:specimenOrObs){
752
            DerivedUnit derivedUnit=null;
753
            if (specimen.isInstanceOf(GatheringEvent.class)){
754
                System.out.println("gathering");
755
                GatheringEvent gath = CdmBase.deproxy(specimen, GatheringEvent.class);
756
            }
757
            if (specimen.isInstanceOf(DerivedUnit.class)){
758
                derivedUnit = CdmBase.deproxy(specimen, DerivedUnit.class);
759
                String unitIDDB = derivedUnit.getCatalogNumber();
760
                if (unitIDDB !=null) {
761
                    if(unitIDDB.equalsIgnoreCase(this.unitID)){
762
                        System.out.println("unitID found");
763

    
764
                        Institution institution = getInstitution(config);
765

    
766
                        Collection col = getCollection(institution, config);
767
                        getCollectionService().saveOrUpdate(col);
768
                        derivedUnit.setCollection(col);
769
                        getOccurrenceService().saveOrUpdate(derivedUnit);
770
                        return result;
771
                    }
772
                }
773
            }
774
            if(specimen.isInstanceOf(IndividualsAssociation.class)) {
775
                System.out.println("Indivi assoc");
776
            }
777
        }
778
        return result;
779
    }
780

    
781

    
782
    private Feature makeFeature(SpecimenOrObservationBase<?> unit) {
783
        if (unit == null){
784
            return null;
785
        }
786
        SpecimenOrObservationType type = unit.getRecordBasis();
787

    
788
        if (type.isFeatureObservation()){
789
            return Feature.OBSERVATION();
790
        }else if (type.isPreservedSpecimen() ||
791
                type == SpecimenOrObservationType.LivingSpecimen ||
792
                type == SpecimenOrObservationType.OtherSpecimen
793
                ){
794
            return Feature.SPECIMEN();
795
        }else if (type == SpecimenOrObservationType.Unknown ||
796
                type == SpecimenOrObservationType.DerivedUnit
797
                ) {
798
            return Feature.INDIVIDUALS_ASSOCIATION();
799
        }
800
        if (DEBUG) {
801
            logger.warn("No feature defined for derived unit class: "
802
                    + unit.getClass().getSimpleName());
803
        }
804
        return null;
805
    }
806

    
807
    private void makeIndividualsAssociation(Taxon taxon, DeterminationEvent determinationEvent, SpecimenSynthesysExcelImportConfigurator config) {
808
        //        try{
809
        //            taxon = (Taxon) getTaxonService().find(taxon.getUuid());
810
        //        }
811
        //        catch(Exception e){
812
        //            //logger.info("taxon uptodate");
813
        //        }
814

    
815
        TaxonDescription taxonDescription=null;
816
        if (taxon.getTitleCache().contains("Chenopodium vulvaria L.")) {
817
            taxonDescription = (TaxonDescription) getDescriptionService().find(UUID.fromString("a60074e7-979b-41fd-ad4d-d391db474ac4"));
818
        }
819
        if(!taxon.getTitleCache().contains("Chenopodium vulvaria L.") || taxonDescription ==null) {
820
            taxonDescription = getTaxonDescription(taxon, ref, false, true);
821
            taxonDescription.setTitleCache(ref.getTitleCache(), true);
822
        }
823

    
824

    
825
        taxon.addDescription(taxonDescription);
826

    
827
        IndividualsAssociation indAssociation = IndividualsAssociation.NewInstance();
828
        Feature feature = makeFeature(derivedUnitBase);
829
        indAssociation.setAssociatedSpecimenOrObservation(derivedUnitBase);
830
        indAssociation.setFeature(feature);
831

    
832
        for (Reference citation : determinationEvent.getReferences()) {
833
            indAssociation.addSource(DescriptionElementSource.NewInstance(OriginalSourceType.Import, null, null, citation, null));
834
        }
835
        indAssociation.addSource(OriginalSourceType.Import, null,null,config.getDataReference(),null);
836

    
837
        taxonDescription.addElement(indAssociation);
838

    
839
        getDescriptionService().saveOrUpdate(taxonDescription);
840
        getTaxonService().saveOrUpdate(taxon);
841
    }
842

    
843
    @Override
844
    protected boolean isIgnore(SpecimenSynthesysExcelImportState state) {
845
        return false;
846
    }
847

    
848
    @Override
849
    protected void doInvoke(SpecimenSynthesysExcelImportState state) {
850
        boolean success = true;
851
        if (state.getConfig().doAskForDate()) {
852
            keepAtomisedDate = askQuestion("Gathering dates can be stored in either atomised fieds (day month year) or in a concatenated field."+
853
                    "\nWhich value do you want to store?\nPress 1 for the atomised, press 2 for the concatenated field, and then press enter.");
854
            useTDWGarea = askQuestion("Use TDWG area or Country/namedarea?\n Press 1 for TDWG areas\n Press 2 for classics Country.");
855
        }
856

    
857
        tx = startTransaction();
858

    
859
        ref = state.getConfig().getTaxonReference();
860
        if (ref == null){
861
            ref = state.getConfig().getSourceReference();
862
        }
863
        AgentBase<?> agent= ref.getAuthorship();
864
        if (agent != null){
865
            if (agent.getClass().equals(Team.class)){
866
                for (Person p : ((Team) agent).getTeamMembers()){
867
                    getAgentService().saveOrUpdate(p);
868
                }
869
            }
870
            if (agent.getClass().equals(Person.class)){
871
                getAgentService().saveOrUpdate(agent);
872
            }
873
        }
874
        getReferenceService().saveOrUpdate(ref);
875
        setClassification(state);
876

    
877
        refreshTransaction();
878

    
879
        URI source = state.getConfig().getSource();
880
        List<Map<String,String>> unitsList = null;
881
        try{
882
            unitsList = ExcelUtils.parseXLS(source);
883
            logger.info("unitslist : "+unitsList.size());
884
        } catch(FileNotFoundException e){
885
            String message = "File not found: " + source;
886
            warnProgress(state, message, e);
887
            logger.error(message);
888
        }
889

    
890
        if (unitsList != null){
891
            //load collectors in the database
892
            if (!state.getConfig().isDebugInstitutionOnly()) {
893
                prepareCollectors(unitsList,state);
894
            }
895

    
896
            List<SpecimenOrObservationBase> specimenOrObs = null;
897
            if (state.getConfig().isDebugInstitutionOnly()){
898
                //DEBUG CHENOPODIUM VULVARIA
899
                UUID uuid = UUID.fromString("85234ff5-8e40-4813-8f06-44ab960a905a");
900
                Taxon taxon = (Taxon)getTaxonService().find(uuid);
901

    
902
                specimenOrObs = getOccurrenceService().listByAssociatedTaxon(null, null, taxon, null, null, null, null, null);
903
            }
904
            Map<String,String> unit=null;
905
            MyHashMap<String,String> myunit;
906
            for (int i=0; i<unitsList.size();i++){
907
                //            for (int i=0; i<10;i++){
908
                if (i%20==0) {
909
                    logger.info("NbUnit prepared: "+i);
910
                    refreshTransaction();
911
                }
912
                unit = unitsList.get(i);
913
                myunit=new MyHashMap<String, String>();
914
                for (String key :unit.keySet()) {
915
                    myunit.put(key, unit.get(key));
916
                }
917
                System.out.println(myunit.toString());
918
                //FIXME do this via state
919
                setUnitPropertiesExcel(myunit, state.getConfig().getDefaultAuthor());//and then invoke
920
                if (state.getConfig().isDebugInstitutionOnly()){
921
                    success &= resetCollectionInstitution(state.getConfig(),specimenOrObs);
922
                } else {
923
                    success &= start(state.getConfig());
924
                }
925
            }
926
        }
927
        if (success == false){
928
            state.setUnsuccessfull();
929
        }
930
        commitTransaction(tx);
931
        return;
932
    }
933

    
934

    
935
    /**
936
     * @param unitsList
937
     * @param state
938
     */
939
    private void prepareCollectors(List<Map<String, String>> unitsList, SpecimenSynthesysExcelImportState state) {
940
        System.out.println("PREPARE COLLECTORS");
941
        List<String> collectors = new ArrayList<>();
942
        List<String> teams = new ArrayList<>();
943
        List<List<String>> collectorinteams = new ArrayList<>();
944
        String tmp;
945
        for (Map<String,String> unit : unitsList){
946
            tmp=null;
947
            tmp = unit.get("collector");
948
            if (tmp != null && !tmp.isEmpty()) {
949
                if (tmp.indexOf("et al.") != -1 || tmp.indexOf(" al. ")!=-1 || tmp.indexOf("& al.")!=-1  ) {
950
                    if (!tmp.trim().isEmpty()) {
951
                        teams.add(tmp.trim());
952
                    }
953
                } else{
954
                    if(tmp.indexOf(" et ")!=-1 || tmp.indexOf("&")!=-1 || tmp.indexOf(";") !=-1){
955
                        List<String> collteam = new ArrayList<String>();
956
                        String[] tmp1 = tmp.split(" et ");
957
                        for (String elt:tmp1){
958
                            String tmp2[] = elt.split("&");
959
                            for (String elt2:tmp2) {
960
                                if (!elt2.trim().isEmpty()) {
961
                                    String tmp3[] = elt.split(";");
962
                                    for (String elt3:tmp3) {
963
                                        if (!elt3.isEmpty()){
964
                                            collectors.add(elt3.trim());
965
                                            collteam.add(elt3.trim());
966
                                        }
967
                                    }
968
                                }
969
                            }
970
                        }
971
                        if (collteam.size()>0) {
972
                            collectorinteams.add(new ArrayList<String>(new HashSet<String>(collteam)));
973
                        }
974
                    }
975
                    else
976
                        if (!tmp.trim().isEmpty() && !tmp.toString().trim().equalsIgnoreCase("none")) {
977
                            collectors.add(tmp.trim());
978
                        }
979
                }
980
            }
981
        }
982

    
983
        List<String> collectorsU = new ArrayList<String>(new HashSet<String>(collectors));
984
        List<String> teamsU = new ArrayList<String>(new HashSet<String>(teams));
985

    
986

    
987
        //existing teams in DB
988
        Map<String,Team> titleCacheTeam = new HashMap<String, Team>();
989
        List<UuidAndTitleCache<Team>> hiberTeam = getAgentService().getTeamUuidAndTitleCache();
990

    
991
        Set<UUID> uuids = new HashSet<UUID>();
992
        for (UuidAndTitleCache<Team> hibernateT:hiberTeam){
993
            uuids.add(hibernateT.getUuid());
994
        }
995
        if (!uuids.isEmpty()){
996
            List<AgentBase> existingTeams = getAgentService().find(uuids);
997
            for (AgentBase<?> existingP:existingTeams){
998
                titleCacheTeam.put(existingP.getTitleCache(),(Team) existingP);
999
            }
1000
        }
1001

    
1002

    
1003
        Map<String,UUID> teamMap = new HashMap<String, UUID>();
1004
        for (UuidAndTitleCache<Team> uuidt:hiberTeam){
1005
            teamMap.put(uuidt.getTitleCache(), uuidt.getUuid());
1006
        }
1007

    
1008
        //existing persons in DB
1009
        List<UuidAndTitleCache<Person>> hiberPersons = getAgentService().getPersonUuidAndTitleCache();
1010
        Map<String,Person> titleCachePerson = new HashMap<String, Person>();
1011
        uuids = new HashSet<UUID>();
1012
        for (UuidAndTitleCache<Person> hibernateP:hiberPersons){
1013
            uuids.add(hibernateP.getUuid());
1014
        }
1015

    
1016
        if (!uuids.isEmpty()){
1017
            List<AgentBase> existingPersons = getAgentService().find(uuids);
1018
            for (AgentBase<?> existingP:existingPersons){
1019
                titleCachePerson.put(existingP.getTitleCache(),CdmBase.deproxy(existingP, Person.class));
1020
            }
1021
        }
1022

    
1023
        Map<String,UUID> personMap = new HashMap<String, UUID>();
1024
        for (UuidAndTitleCache<Person> person:hiberPersons){
1025
            personMap.put(person.getTitleCache(), person.getUuid());
1026
        }
1027

    
1028
        java.util.Collection<AgentBase> personsToAdd = new ArrayList<AgentBase>();
1029
        java.util.Collection<AgentBase> teamsToAdd = new ArrayList<AgentBase>();
1030

    
1031
        for (String collector:collectorsU){
1032
            Person p = Person.NewInstance();
1033
            p.setTitleCache(collector,true);
1034
            if (!personMap.containsKey(p.getTitleCache())){
1035
                personsToAdd.add(p);
1036
            }
1037
        }
1038
        for (String team:teamsU){
1039
            Team p = Team.NewInstance();
1040
            p.setTitleCache(team,true);
1041
            if (!teamMap.containsKey(p.getTitleCache())){
1042
                teamsToAdd.add(p);
1043
            }
1044
        }
1045
        Map<UUID, AgentBase> uuuidPerson = getAgentService().save(personsToAdd);
1046
        for (UUID u:uuuidPerson.keySet()){
1047
            titleCachePerson.put(uuuidPerson.get(u).getTitleCache(),CdmBase.deproxy(uuuidPerson.get(u), Person.class) );
1048
        }
1049

    
1050

    
1051
        Person ptmp ;
1052
        Map <String,Integer>teamdone = new HashMap<String, Integer>();
1053
        for (List<String> collteam: collectorinteams){
1054
            if (!teamdone.containsKey(StringUtils.join(collteam.toArray(),"-"))){
1055
                Team team = new Team();
1056
                boolean em =true;
1057
                for (String collector:collteam){
1058
                    ptmp = Person.NewInstance();
1059
                    ptmp.setTitleCache(collector,true);
1060
                    Person p2 = titleCachePerson.get(ptmp.getTitleCache());
1061
                    team.addTeamMember(p2);
1062
                    em=false;
1063
                }
1064
                if (!em) {
1065
                    teamsToAdd.add(team);
1066
                }
1067
                teamdone.put(StringUtils.join(collteam.toArray(),"-"),0);
1068
            }
1069
        }
1070

    
1071

    
1072
        Map<UUID, AgentBase> uuuidTeam =  getAgentService().save(teamsToAdd);
1073

    
1074
        for (UUID u:uuuidTeam.keySet()){
1075
            titleCacheTeam.put(uuuidTeam.get(u).getTitleCache(), (Team) uuuidTeam.get(u) );
1076
        }
1077

    
1078
        state.getConfig().setTeams(titleCacheTeam);
1079
        state.getConfig().setPersons(titleCachePerson);
1080
    }
1081

    
1082
    private boolean askQuestion(String question){
1083
        Scanner scan = new Scanner(System.in);
1084
        System.out.println(question);
1085
        int index = scan.nextInt();
1086
        if (index == 1) {
1087
            return true;
1088
        } else {
1089
            return false;
1090
        }
1091
    }
1092

    
1093

    
1094
    @Override
1095
    protected boolean doCheck(SpecimenSynthesysExcelImportState state) {
1096
        logger.warn("Validation not yet implemented for " + getClass().getSimpleName());
1097
        return true;
1098
    }
1099
}
(12-12/12)