Project

General

Profile

Download (43.3 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.DefinedTermBase;
42
import eu.etaxonomy.cdm.model.common.Language;
43
import eu.etaxonomy.cdm.model.common.OriginalSourceType;
44
import eu.etaxonomy.cdm.model.common.TimePeriod;
45
import eu.etaxonomy.cdm.model.description.DescriptionElementSource;
46
import eu.etaxonomy.cdm.model.description.Feature;
47
import eu.etaxonomy.cdm.model.description.IndividualsAssociation;
48
import eu.etaxonomy.cdm.model.description.TaxonDescription;
49
import eu.etaxonomy.cdm.model.location.NamedArea;
50
import eu.etaxonomy.cdm.model.media.Media;
51
import eu.etaxonomy.cdm.model.name.ITaxonNameBase;
52
import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
53
import eu.etaxonomy.cdm.model.name.TaxonName;
54
import eu.etaxonomy.cdm.model.name.TaxonNameFactory;
55
import eu.etaxonomy.cdm.model.occurrence.Collection;
56
import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
57
import eu.etaxonomy.cdm.model.occurrence.DeterminationEvent;
58
import eu.etaxonomy.cdm.model.occurrence.GatheringEvent;
59
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
60
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationType;
61
import eu.etaxonomy.cdm.model.reference.Reference;
62
import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
63
import eu.etaxonomy.cdm.model.taxon.Classification;
64
import eu.etaxonomy.cdm.model.taxon.Taxon;
65
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
66
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
67
import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
68
import eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl;
69
import eu.etaxonomy.cdm.strategy.parser.TimePeriodParser;
70

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

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

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

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

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

    
119
    boolean DEBUG =false;
120

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

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

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

    
151

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

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

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

    
217
        }
218
    }
219

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

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

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

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

    
267
        accessionNumber = null;
268

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

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

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

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

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

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

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

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

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

    
321

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

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

    
385
        }
386
        return collection;
387
    }
388

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

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

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

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

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

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

    
466

    
467

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

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

    
480
            makeIndividualsAssociation(taxon,determinationEvent,config);
481

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

    
485
    }
486

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

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

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

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

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

    
565
    }
566

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

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

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

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

    
611
        //        refreshTransaction();
612
        try {
613

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

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

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

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

    
658

    
659

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

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

    
676

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

    
683

    
684

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

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

    
706

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

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

    
724
            getOccurrenceService().saveOrUpdate(derivedUnitBase);
725

    
726
            setTaxonName(config);
727

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

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

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

    
751

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

    
765
                        Institution institution = getInstitution(config);
766

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

    
782

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

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

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

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

    
825

    
826
        taxon.addDescription(taxonDescription);
827

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

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

    
838
        taxonDescription.addElement(indAssociation);
839

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

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

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

    
858
        tx = startTransaction();
859

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

    
878
        refreshTransaction();
879

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

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

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

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

    
935

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

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

    
987

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

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

    
1003

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

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

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

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

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

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

    
1051

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

    
1072

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

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

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

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

    
1094

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