2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
9 package eu
.etaxonomy
.cdm
.io
.specimen
.excel
.in
;
11 import java
.io
.FileNotFoundException
;
12 import java
.net
.MalformedURLException
;
13 import java
.util
.ArrayList
;
14 import java
.util
.Calendar
;
15 import java
.util
.HashMap
;
16 import java
.util
.HashSet
;
17 import java
.util
.List
;
19 import java
.util
.Scanner
;
21 import java
.util
.UUID
;
23 import org
.apache
.commons
.lang3
.StringUtils
;
24 import org
.apache
.logging
.log4j
.LogManager
;
25 import org
.apache
.logging
.log4j
.Logger
;
26 import org
.springframework
.stereotype
.Component
;
27 import org
.springframework
.transaction
.TransactionStatus
;
29 import eu
.etaxonomy
.cdm
.common
.ExcelUtils
;
30 import eu
.etaxonomy
.cdm
.common
.URI
;
31 import eu
.etaxonomy
.cdm
.facade
.DerivedUnitFacade
;
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
.TimePeriod
;
43 import eu
.etaxonomy
.cdm
.model
.description
.DescriptionElementSource
;
44 import eu
.etaxonomy
.cdm
.model
.description
.Feature
;
45 import eu
.etaxonomy
.cdm
.model
.description
.IndividualsAssociation
;
46 import eu
.etaxonomy
.cdm
.model
.description
.TaxonDescription
;
47 import eu
.etaxonomy
.cdm
.model
.location
.NamedArea
;
48 import eu
.etaxonomy
.cdm
.model
.media
.Media
;
49 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalCode
;
50 import eu
.etaxonomy
.cdm
.model
.name
.TaxonName
;
51 import eu
.etaxonomy
.cdm
.model
.name
.TaxonNameFactory
;
52 import eu
.etaxonomy
.cdm
.model
.occurrence
.Collection
;
53 import eu
.etaxonomy
.cdm
.model
.occurrence
.DerivedUnit
;
54 import eu
.etaxonomy
.cdm
.model
.occurrence
.DeterminationEvent
;
55 import eu
.etaxonomy
.cdm
.model
.occurrence
.GatheringEvent
;
56 import eu
.etaxonomy
.cdm
.model
.occurrence
.SpecimenOrObservationBase
;
57 import eu
.etaxonomy
.cdm
.model
.occurrence
.SpecimenOrObservationType
;
58 import eu
.etaxonomy
.cdm
.model
.reference
.OriginalSourceType
;
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
;
76 public class SpecimenSythesysExcelImport
extends CdmImportBase
<SpecimenSynthesysExcelImportConfigurator
, SpecimenSynthesysExcelImportState
>
77 implements ICdmIO
<SpecimenSynthesysExcelImportState
> {
79 private static final long serialVersionUID
= -1145031415387024364L;
80 private static final Logger logger
= LogManager
.getLogger();
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
;
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
;
108 private DerivedUnit derivedUnitBase
;
109 private Reference ref
= null;
110 private TransactionStatus tx
;
111 private Classification classification
= null;
113 protected ArrayList
<String
> identificationList
= new ArrayList
<>();
114 protected ArrayList
<String
> multimediaObjects
= new ArrayList
<>();
115 private boolean keepAtomisedDate
=true;
116 private boolean useTDWGarea
= true;
118 boolean DEBUG
=false;
120 public SpecimenSythesysExcelImport() {
125 * private HashMap that handle null values (missing keys)
126 * return empty string instead of null
128 public class MyHashMap
<K
,V
> extends HashMap
<K
,V
> {
130 private static final long serialVersionUID
= -6230407405666753405L;
132 @SuppressWarnings("unchecked")
134 public V
get(Object key
) {
136 if (containsKey(key
)) {
141 if (a
==null || a
.toString().equalsIgnoreCase("none")) {
150 * getClassification : get the classification declared in the ImportState
155 private void setClassification(SpecimenSynthesysExcelImportState state
) {
156 if (classification
== null){
157 boolean configreused
=false;
158 if (state
.getConfig().getClassificationName()!=null && state
.getConfig().getClassificationName().equalsIgnoreCase("Goosefoots")) {
159 classification
= getClassificationService().find(UUID
.fromString("2c2dc41c-9891-42cd-9cd5-8b28dfdd1b8a"));
160 if (classification
==null){
161 String name
= state
.getConfig().getClassificationName();
162 classification
= Classification
.NewInstance(name
, ref
, Language
.DEFAULT());
163 getClassificationService().saveOrUpdate(classification
);
167 if (state
.getConfig().getClassificationName()!=null && state
.getConfig().getClassificationName().equalsIgnoreCase("Ants")) {
168 classification
= getClassificationService().find(UUID
.fromString("9b72d32f-2868-4f0d-81bd-ebc38ee8c645"));
169 if (classification
==null){
170 String name
= state
.getConfig().getClassificationName();
171 classification
= Classification
.NewInstance(name
, ref
, Language
.DEFAULT());
172 getClassificationService().saveOrUpdate(classification
);
176 if (state
.getConfig().getClassificationName()!=null && state
.getConfig().getClassificationName().equalsIgnoreCase("Fungi")) {
177 classification
= getClassificationService().find(UUID
.fromString("fe07274d-daff-4678-9f7d-2c3916948c3e"));
178 if (classification
==null){
179 String name
= state
.getConfig().getClassificationName();
180 classification
= Classification
.NewInstance(name
, ref
, Language
.DEFAULT());
181 getClassificationService().saveOrUpdate(classification
);
185 if (state
.getConfig().getClassificationName()!=null && state
.getConfig().getClassificationName().equalsIgnoreCase("Campylopus")) {
186 classification
= getClassificationService().find(UUID
.fromString("9dccbd11-eb0e-4cac-ae04-aa61ad82b8a6"));
187 if (classification
==null){
188 String name
= state
.getConfig().getClassificationName();
189 classification
= Classification
.NewInstance(name
, ref
, Language
.DEFAULT());
190 getClassificationService().saveOrUpdate(classification
);
195 if (state
.getConfig().getClassificationName()!=null && state
.getConfig().getClassificationName().equalsIgnoreCase("Eupolybothrus")) {
196 classification
= getClassificationService().find(UUID
.fromString("62ce65e0-e036-49aa-aae7-4d4d0f88966c"));
197 if (classification
==null){
198 String name
= state
.getConfig().getClassificationName();
199 classification
= Classification
.NewInstance(name
, ref
, Language
.DEFAULT());
200 getClassificationService().saveOrUpdate(classification
);
206 String name
= state
.getConfig().getClassificationName();
207 classification
= Classification
.NewInstance(name
, ref
, Language
.DEFAULT());
208 if (state
.getConfig().getClassificationUuid() != null) {
209 classification
.setUuid(state
.getConfig().getClassificationUuid());
211 getClassificationService().saveOrUpdate(classification
);
217 * refresh the hibernate transaction :
218 * - commit the current queries
219 * - get the reference and the classification and the derivedUnitBase back from the hibernate session
221 private void refreshTransaction(){
222 commitTransaction(tx
);
223 tx
= startTransaction();
224 ref
= getReferenceService().find(ref
.getUuid());
225 classification
= getClassificationService().find(classification
.getUuid());
227 derivedUnitBase
= (DerivedUnit
) getOccurrenceService().find(derivedUnitBase
.getUuid());
229 //logger.warn("derivedunit up to date or not created yet");
234 // * refresh the hibernate transaction :
235 // * - commit the current queries
236 // * - get the reference and the classification and the derivedUnitBase back from the hibernate session
238 // private void refreshTransac(){
239 // commitTransaction(tx);
240 // tx = startTransaction();
243 * Store the unit's properties into variables
244 * @param unit: the hashmap containing the splitted Excel line (Key=column name, value=value)
246 private void setUnitPropertiesExcel(MyHashMap
<String
,String
> unit
, String defaultAuthor
){
247 multimediaObjects
= new ArrayList
<String
>();
248 identificationList
= new ArrayList
<String
>();
252 String author
= unit
.get("author");
253 if (author
.isEmpty() && !defaultAuthor
.isEmpty()) {
254 author
=defaultAuthor
;
256 String taxonName
= unit
.get("taxonName");
258 institutionCode
= unit
.get("institution");
259 collectionCode
= unit
.get("collection");
260 unitID
= unit
.get("unitID");
261 recordBasis
= unit
.get("recordBasis");
263 accessionNumber
= null;
265 try {longitude
= Double
.valueOf(unit
.get("longitude"));
266 } catch (Exception e
) {longitude
= 0.0;}
268 try {latitude
= Double
.valueOf(unit
.get("latitude"));
269 } catch (Exception e
) {latitude
= 0.0;}
271 country
= unit
.get("country");
272 isocountry
= unit
.get("isoCountry");
273 locality
= unit
.get("locality");
274 String habitat
= unit
.get("habitat");
275 String stateProvince
= unit
.get("stateProvince");
276 if (!stateProvince
.isEmpty()) {
277 locality
=stateProvince
+", "+locality
;
279 if (!habitat
.isEmpty()){
280 locality
+=" (Habitat: "+habitat
+")";
283 fieldNumber
= unit
.get("field number");
285 String url
=unit
.get("url");
286 if (!url
.isEmpty()) {
287 multimediaObjects
.add(url
);
290 String coll
=unit
.get("collector");
291 if (!coll
.isEmpty()) {
292 if (coll
.indexOf("& al.")!=-1 || coll
.indexOf("et al.") != -1 || coll
.indexOf(" al. ")!=-1 ||
293 coll
.indexOf("&") != -1 || coll
.indexOf(" et ") != -1 || coll
.indexOf(";")!=-1) {
294 gatheringTeam
= coll
;
297 gatheringAgent
= coll
;
301 if(!taxonName
.contains(author
)) {
302 identificationList
.add(taxonName
+" "+author
);
304 identificationList
.add(taxonName
);
307 gatheringYear
= unit
.get("year");
308 gatheringMonth
= unit
.get("month");
309 gatheringDay
= unit
.get("day");
310 gatheringDate
= unit
.get("date");
312 gatheringNotes
= unit
.get("eventRemarks");
313 originalsource
= unit
.get("originalsource");
314 identifier
= unit
.get("identifier");
317 private Institution
getInstitution(SpecimenSynthesysExcelImportConfigurator config
){
318 Institution institution
;
319 List
<Institution
> institutions
;
321 institutions
= getAgentService().searchInstitutionByCode(institutionCode
);
323 institutions
=new ArrayList
<Institution
>();
325 if (institutions
.size() ==0 || !config
.getReUseExistingMetadata()){
326 logger
.debug("Institution (agent) unknown or not allowed to reuse existing metadata");
328 institution
= Institution
.NewInstance();
329 institution
.setCode(institutionCode
);
330 getAgentService().saveOrUpdate(institution
);
333 logger
.debug("Institution (agent) already in the db");
334 institution
= institutions
.get(0);
336 return CdmBase
.deproxy(institution
, Institution
.class);
340 * Look if the Collection does already exists
341 * @param collectionCode: a string
342 * @param institution: the current Institution
344 * @return the Collection (existing or new)
346 private Collection
getCollection(Institution institution
, SpecimenSynthesysExcelImportConfigurator config
){
347 Collection collection
=null;
348 List
<Collection
> collections
;
350 collections
= getCollectionService().searchByCode(collectionCode
);
352 collections
=new ArrayList
<Collection
>();
354 if (collections
.size() ==0 || !config
.getReUseExistingMetadata()){
355 logger
.debug("Collection not found or do not reuse existing metadata "+collectionCode
);
356 //create new collection
357 collection
= Collection
.NewInstance();
358 collection
.setCode(collectionCode
);
359 collection
.setCodeStandard("GBIF");
360 collection
.setInstitute(institution
);
363 boolean collectionFound
=false;
364 for (int i
=0; i
<collections
.size(); i
++){
365 collection
= collections
.get(i
);
367 if (collection
.getInstitute().getCode().equalsIgnoreCase(institution
.getCode())){
368 //found a collection with the same code and the same institution
369 collectionFound
=true;
371 } catch (NullPointerException e
) {}
373 if (!collectionFound
){
374 collection
= Collection
.NewInstance();
375 collection
.setCode(collectionCode
);
376 collection
.setCodeStandard("GBIF");
377 collection
.setInstitute(institution
);
384 private void setTaxonName(SpecimenSynthesysExcelImportConfigurator config
){
385 TaxonName taxonName
= null;
388 String scientificName
="";
389 boolean preferredFlag
=false;
391 for (int i
= 0; i
< identificationList
.size(); i
++) {
392 String fullScientificNameString
= identificationList
.get(i
);
393 fullScientificNameString
= fullScientificNameString
.replaceAll(" et ", " & ");
394 if (fullScientificNameString
.indexOf("_preferred_") != -1){
395 scientificName
= fullScientificNameString
.split("_preferred_")[0].trim();
396 String pTmp
= fullScientificNameString
.split("_preferred_")[1].split("_code_")[0];
397 if (pTmp
== "1" || pTmp
.toLowerCase().indexOf("true") != -1) {
403 scientificName
= fullScientificNameString
.trim();
406 if (fullScientificNameString
.indexOf("_code_") != -1){
407 nomenclatureCode
= fullScientificNameString
.split("_code_")[1].trim();
410 if (config
.getDoReUseTaxon()){
411 List
<TaxonBase
> c
= null;
413 Taxon cc
= getTaxonService().findBestMatchingTaxon(scientificName
);
415 if ((cc
.getSec() == null || cc
.getSec().toString().isEmpty()) || (cc
.getSec() != null &&
416 cc
.getSec().getTitleCache().equalsIgnoreCase(ref
.getTitleCache()))) {
417 if(cc
.getSec() == null || cc
.getSec().toString().isEmpty()){
419 getTaxonService().saveOrUpdate(cc
);
425 c
= getTaxonService().searchByName(scientificName
, INCLUDE_UNPUBLISHED
, ref
);
426 for (TaxonBase
<?
> b
: c
) {
430 } catch (Exception e
) {
431 logger
.info("Searchtaxabyname failed" + e
);
436 if (!config
.getDoReUseTaxon() || taxon
== null){
438 logger
.info("create new taxonName instance");
440 if (config
.getDoAutomaticParsing()){
441 taxonName
= parseScientificName(scientificName
);
444 taxonName
= TaxonNameFactory
.NewNonViralInstance(null);
445 taxonName
.setTitleCache(scientificName
, true);
447 getNameService().save(taxonName
);
448 taxon
= Taxon
.NewInstance(taxonName
, ref
); //sec set null
449 getTaxonService().save(taxon
);
450 // refreshTransaction();
451 taxon
= (Taxon
) getTaxonService().find(taxon
.getUuid());
452 taxon
= addTaxonNode(taxon
, config
);
455 DeterminationEvent determinationEvent
= DeterminationEvent
.NewInstance();
456 determinationEvent
.setTaxon(getTaxonService().find(taxon
.getUuid()));
457 determinationEvent
.setPreferredFlag(preferredFlag
);
459 determinationEvent
.setIdentifiedUnit(derivedUnitBase
);
460 if (!identifier
.isEmpty()){
461 Person p
= Person
.NewInstance();
462 p
.setTitleCache(identifier
, true);
463 determinationEvent
.setActor(p
);
465 derivedUnitBase
.addDetermination(determinationEvent
);
467 makeIndividualsAssociation(taxon
,determinationEvent
,config
);
469 getOccurrenceService().saveOrUpdate(derivedUnitBase
);
473 private Taxon
addTaxonNode(Taxon taxon
, SpecimenSynthesysExcelImportConfigurator config
) {
475 logger
.info("link taxon to a taxonNode");
477 boolean exist
= false;
478 for (TaxonNode p
: classification
.getAllNodes()){
479 if(p
.getTaxon().equals(taxon
)) {
484 taxon
= (Taxon
) getTaxonService().find(taxon
.getUuid());
485 classification
.addChildTaxon(taxon
, ref
, null);
486 getClassificationService().saveOrUpdate(classification
);
487 // refreshTransaction();
489 return (Taxon
) getTaxonService().find(taxon
.getUuid());
492 private TaxonName
parseScientificName(String scientificName
){
494 logger
.debug("in parseScientificName");
496 NonViralNameParserImpl nvnpi
= NonViralNameParserImpl
.NewInstance();
497 TaxonName taxonName
= null;
498 boolean problem
=false;
501 logger
.debug("nomenclature: "+nomenclatureCode
);
504 if(nomenclatureCode
== null){
505 taxonName
= TaxonNameFactory
.NewNonViralInstance(null);
506 taxonName
.setTitleCache(scientificName
, true);
510 if (nomenclatureCode
.toString().equals("Zoological")){
511 taxonName
= (TaxonName
)nvnpi
.parseFullName(scientificName
,NomenclaturalCode
.ICZN
,null);
512 if (taxonName
.hasProblem()) {
516 if (nomenclatureCode
.toString().equals("Botanical")){
517 taxonName
= (TaxonName
)nvnpi
.parseFullName(scientificName
,NomenclaturalCode
.ICNAFP
,null);
518 if (taxonName
.hasProblem()) {
521 if (nomenclatureCode
.toString().equals("Bacterial")){
522 taxonName
= (TaxonName
)nvnpi
.parseFullName(scientificName
,NomenclaturalCode
.ICNP
, null);
523 if (taxonName
.hasProblem()) {
527 if (nomenclatureCode
.toString().equals("Cultivar")){
528 taxonName
= (TaxonName
)nvnpi
.parseFullName(scientificName
,NomenclaturalCode
.ICNCP
, null);
529 if (taxonName
.hasProblem()) {
533 // if (nomenclatureCode.toString().equals("Viral")){
534 // ViralName taxonName = (ViralName)nvnpi.parseFullName(scientificName,NomenclaturalCode.ICVCN(), null);
535 // if (taxonName.hasProblem())
536 // System.out.println("pb ICVCN");
538 //TODO: parsing of ViralNames?
540 taxonName
= TaxonNameFactory
.NewNonViralInstance(null);
541 taxonName
.setTitleCache(scientificName
, true);
547 private DerivedUnitFacade
getFacade() {
548 // logger.info("GETFACADE");
550 * SPECIMEN OR OBSERVATION OR LIVING
552 // DerivedUnit derivedThing = null;
553 SpecimenOrObservationType type
= null;
556 if (recordBasis
!= null) {
557 String rec
= recordBasis
.toLowerCase();
558 if (rec
.contains("specimen") || rec
.startsWith("s")) {// specimen
559 type
= SpecimenOrObservationType
.PreservedSpecimen
;
561 if (rec
.contains("observat") || rec
.startsWith("o")) {
562 type
= SpecimenOrObservationType
.Observation
;
564 if (rec
.contains("fossil") || rec
.startsWith("f") ){
565 type
= SpecimenOrObservationType
.Fossil
;
568 if (rec
.contains("living") || rec
.startsWith("l")) {
569 type
= SpecimenOrObservationType
.LivingSpecimen
;
573 logger
.info("The basis of record does not seem to be known: " + recordBasis
);
575 type
= SpecimenOrObservationType
.DerivedUnit
;
578 logger
.info("The basis of record is null");
579 type
= SpecimenOrObservationType
.DerivedUnit
;
581 DerivedUnitFacade derivedUnitFacade
= DerivedUnitFacade
.NewInstance(type
);
582 return derivedUnitFacade
;
586 * Store the unit with it's Gathering informations in the CDM
588 public boolean start(SpecimenSynthesysExcelImportConfigurator config
){
589 boolean result
= true;
591 // refreshTransaction();
595 * SPECIMEN OR OBSERVATION OR LIVING
597 DerivedUnitFacade derivedUnitFacade
= getFacade();
598 derivedUnitBase
= derivedUnitFacade
.innerDerivedUnit();
600 //set catalogue number (unitID)
601 derivedUnitFacade
.setCatalogNumber(unitID
);
602 derivedUnitFacade
.setAccessionNumber(accessionNumber
);
604 if (!originalsource
.isEmpty()){
605 Reference reference
= ReferenceFactory
.newGeneric();
606 reference
.setTitleCache(originalsource
, true);
607 derivedUnitBase
.addSource(OriginalSourceType
.Import
, originalsource
, "", reference
, "");
609 derivedUnitBase
.addSource(OriginalSourceType
.Import
, unitID
,"",ref
,ref
.getCitation());
612 * INSTITUTION & COLLECTION
615 if (!institutionCode
.isEmpty()){
616 Institution institution
= getInstitution(config
);
618 if (!collectionCode
.isEmpty()){
619 Collection collection
= getCollection(institution
, config
);
620 //link specimen & collection
621 derivedUnitFacade
.setCollection(collection
);
629 UnitsGatheringEvent unitsGatheringEvent
= new UnitsGatheringEvent(getTermService(), locality
, languageIso
,
630 longitude
, latitude
, gatheringAgent
, gatheringTeam
,config
);
632 UnitsGatheringArea unitsGatheringArea
= new UnitsGatheringArea();
633 unitsGatheringArea
.useTDWGareas(this.useTDWGarea
);
634 // unitsGatheringArea.setConfig(config, getOccurrenceService(),getTermService());
635 unitsGatheringArea
.setParams(isocountry
, country
, config
, getTermService(), getVocabularyService());
636 DefinedTermBase areaCountry
=unitsGatheringArea
.getCountry();
640 // copy gathering event to facade
641 GatheringEvent gatheringEvent
= unitsGatheringEvent
.getGatheringEvent();
642 //join gatheringEvent to fieldObservation
643 derivedUnitFacade
.setGatheringEvent(gatheringEvent
);
645 derivedUnitFacade
.setLocality(gatheringEvent
.getLocality());
646 derivedUnitFacade
.setExactLocation(gatheringEvent
.getExactLocation());
647 //derivedUnitFacade.setCollector(gatheringEvent.getCollector());
648 derivedUnitFacade
.setCountry((NamedArea
)areaCountry
);
649 for(DefinedTermBase
<?
> area
:unitsGatheringArea
.getAreas()){
650 derivedUnitFacade
.addCollectingArea((NamedArea
) area
);
652 if (gatheringNotes
!= null && !gatheringNotes
.isEmpty()) {
653 derivedUnitFacade
.setFieldNotes(gatheringNotes
);
658 * merge AND STORE DATA
660 // getTermService().saveOrUpdate(areaCountry);// TODO save area sooner
661 getTermService().saveLanguageData(unitsGatheringEvent
.getLocality());
666 if (keepAtomisedDate
&& (!gatheringYear
.isEmpty() || !gatheringMonth
.isEmpty() || !gatheringDay
.isEmpty())){
667 Calendar calendar
= Calendar
.getInstance();
668 if (!gatheringYear
.isEmpty()) {
669 TimePeriod tp
= TimePeriod
.NewInstance(Integer
.parseInt(gatheringYear
));
670 if (!gatheringMonth
.isEmpty()) {
671 tp
.setStartMonth(Integer
.parseInt(gatheringMonth
));
672 if (!gatheringDay
.isEmpty()) {
673 tp
.setStartDay(Integer
.parseInt(gatheringDay
));
676 unitsGatheringEvent
.setGatheringDate(tp
);
680 if (!gatheringDate
.isEmpty()){
681 TimePeriod tp
= TimePeriodParser
.parseString(gatheringDate
);
682 unitsGatheringEvent
.setGatheringDate(tp
);
688 derivedUnitFacade
.setFieldNumber(fieldNumber
);
690 //add Multimedia URLs
691 if(multimediaObjects
.size()>0){
692 for (String multimediaObject
: multimediaObjects
) {
695 media
= getImageMedia(multimediaObject
, READ_MEDIA_DATA
);
696 derivedUnitFacade
.addDerivedUnitMedia(media
);
697 } catch (MalformedURLException e
) {
698 // TODO Auto-generated catch block
704 getOccurrenceService().saveOrUpdate(derivedUnitBase
);
706 setTaxonName(config
);
708 // refreshTransaction();
710 logger
.info("saved new specimen ...");
713 } catch (Exception e
) {
714 logger
.warn("Error when reading record!!");
719 logger
.info("commit done");
726 * Store the unit with it's Gathering informations in the CDM
728 public boolean resetCollectionInstitution(SpecimenSynthesysExcelImportConfigurator config
,List
<SpecimenOrObservationBase
> specimenOrObs
){
729 boolean result
= true;
732 for (SpecimenOrObservationBase
<?
> specimen
:specimenOrObs
){
733 DerivedUnit derivedUnit
=null;
734 if (specimen
.isInstanceOf(GatheringEvent
.class)){
735 System
.out
.println("gathering");
736 GatheringEvent gath
= CdmBase
.deproxy(specimen
, GatheringEvent
.class);
738 if (specimen
.isInstanceOf(DerivedUnit
.class)){
739 derivedUnit
= CdmBase
.deproxy(specimen
, DerivedUnit
.class);
740 String unitIDDB
= derivedUnit
.getCatalogNumber();
741 if (unitIDDB
!=null) {
742 if(unitIDDB
.equalsIgnoreCase(this.unitID
)){
743 System
.out
.println("unitID found");
745 Institution institution
= getInstitution(config
);
747 Collection col
= getCollection(institution
, config
);
748 getCollectionService().saveOrUpdate(col
);
749 derivedUnit
.setCollection(col
);
750 getOccurrenceService().saveOrUpdate(derivedUnit
);
755 if(specimen
.isInstanceOf(IndividualsAssociation
.class)) {
756 System
.out
.println("Indivi assoc");
763 private Feature
makeFeature(SpecimenOrObservationBase
<?
> unit
) {
767 SpecimenOrObservationType type
= unit
.getRecordBasis();
769 if (type
.isFeatureObservation()){
770 return Feature
.OBSERVATION();
771 }else if (type
.isPreservedSpecimen() ||
772 type
== SpecimenOrObservationType
.LivingSpecimen
||
773 type
== SpecimenOrObservationType
.OtherSpecimen
775 return Feature
.SPECIMEN();
776 }else if (type
== SpecimenOrObservationType
.Unknown
||
777 type
== SpecimenOrObservationType
.DerivedUnit
779 return Feature
.INDIVIDUALS_ASSOCIATION();
782 logger
.warn("No feature defined for derived unit class: "
783 + unit
.getClass().getSimpleName());
788 private void makeIndividualsAssociation(Taxon taxon
, DeterminationEvent determinationEvent
, SpecimenSynthesysExcelImportConfigurator config
) {
790 // taxon = (Taxon) getTaxonService().find(taxon.getUuid());
792 // catch(Exception e){
793 // //logger.info("taxon uptodate");
796 TaxonDescription taxonDescription
=null;
797 if (taxon
.getTitleCache().contains("Chenopodium vulvaria L.")) {
798 taxonDescription
= (TaxonDescription
) getDescriptionService().find(UUID
.fromString("a60074e7-979b-41fd-ad4d-d391db474ac4"));
800 if(!taxon
.getTitleCache().contains("Chenopodium vulvaria L.") || taxonDescription
==null) {
801 taxonDescription
= getTaxonDescription(taxon
, ref
, false, true);
802 taxonDescription
.setTitleCache(ref
.getTitleCache(), true);
806 taxon
.addDescription(taxonDescription
);
808 IndividualsAssociation indAssociation
= IndividualsAssociation
.NewInstance();
809 Feature feature
= makeFeature(derivedUnitBase
);
810 indAssociation
.setAssociatedSpecimenOrObservation(derivedUnitBase
);
811 indAssociation
.setFeature(feature
);
813 for (Reference citation
: determinationEvent
.getReferences()) {
814 indAssociation
.addSource(DescriptionElementSource
.NewInstance(OriginalSourceType
.Import
, null, null, citation
, null));
816 indAssociation
.addSource(OriginalSourceType
.Import
, null,null,config
.getDataReference(),null);
818 taxonDescription
.addElement(indAssociation
);
820 getDescriptionService().saveOrUpdate(taxonDescription
);
821 getTaxonService().saveOrUpdate(taxon
);
825 protected boolean isIgnore(SpecimenSynthesysExcelImportState state
) {
830 protected void doInvoke(SpecimenSynthesysExcelImportState state
) {
831 boolean success
= true;
832 if (state
.getConfig().doAskForDate()) {
833 keepAtomisedDate
= askQuestion("Gathering dates can be stored in either atomised fieds (day month year) or in a concatenated field."+
834 "\nWhich value do you want to store?\nPress 1 for the atomised, press 2 for the concatenated field, and then press enter.");
835 useTDWGarea
= askQuestion("Use TDWG area or Country/namedarea?\n Press 1 for TDWG areas\n Press 2 for classics Country.");
838 tx
= startTransaction();
840 ref
= state
.getConfig().getTaxonReference();
842 ref
= state
.getConfig().getSourceReference();
844 AgentBase
<?
> agent
= ref
.getAuthorship();
846 if (agent
.getClass().equals(Team
.class)){
847 for (Person p
: ((Team
) agent
).getTeamMembers()){
848 getAgentService().saveOrUpdate(p
);
851 if (agent
.getClass().equals(Person
.class)){
852 getAgentService().saveOrUpdate(agent
);
855 getReferenceService().saveOrUpdate(ref
);
856 setClassification(state
);
858 refreshTransaction();
860 URI source
= state
.getConfig().getSource();
861 List
<Map
<String
,String
>> unitsList
= null;
863 unitsList
= ExcelUtils
.parseXLS(source
);
864 logger
.info("unitslist : "+unitsList
.size());
865 } catch(FileNotFoundException e
){
866 String message
= "File not found: " + source
;
867 warnProgress(state
, message
, e
);
868 logger
.error(message
);
871 if (unitsList
!= null){
872 //load collectors in the database
873 if (!state
.getConfig().isDebugInstitutionOnly()) {
874 prepareCollectors(unitsList
,state
);
877 List
<SpecimenOrObservationBase
> specimenOrObs
= null;
878 if (state
.getConfig().isDebugInstitutionOnly()){
879 //DEBUG CHENOPODIUM VULVARIA
880 UUID uuid
= UUID
.fromString("85234ff5-8e40-4813-8f06-44ab960a905a");
881 Taxon taxon
= (Taxon
)getTaxonService().find(uuid
);
883 specimenOrObs
= getOccurrenceService().listByAssociatedTaxon(null, null, taxon
, null, null, null, null, null);
885 Map
<String
,String
> unit
=null;
886 MyHashMap
<String
,String
> myunit
;
887 for (int i
=0; i
<unitsList
.size();i
++){
888 // for (int i=0; i<10;i++){
890 logger
.info("NbUnit prepared: "+i
);
891 refreshTransaction();
893 unit
= unitsList
.get(i
);
894 myunit
=new MyHashMap
<String
, String
>();
895 for (String key
:unit
.keySet()) {
896 myunit
.put(key
, unit
.get(key
));
898 System
.out
.println(myunit
.toString());
899 //FIXME do this via state
900 setUnitPropertiesExcel(myunit
, state
.getConfig().getDefaultAuthor());//and then invoke
901 if (state
.getConfig().isDebugInstitutionOnly()){
902 success
&= resetCollectionInstitution(state
.getConfig(),specimenOrObs
);
904 success
&= start(state
.getConfig());
908 if (success
== false){
909 state
.setUnsuccessfull();
911 commitTransaction(tx
);
915 private void prepareCollectors(List
<Map
<String
, String
>> unitsList
, SpecimenSynthesysExcelImportState state
) {
916 System
.out
.println("PREPARE COLLECTORS");
917 List
<String
> collectors
= new ArrayList
<>();
918 List
<String
> teams
= new ArrayList
<>();
919 List
<List
<String
>> collectorinteams
= new ArrayList
<>();
921 for (Map
<String
,String
> unit
: unitsList
){
923 tmp
= unit
.get("collector");
924 if (tmp
!= null && !tmp
.isEmpty()) {
925 if (tmp
.indexOf("et al.") != -1 || tmp
.indexOf(" al. ")!=-1 || tmp
.indexOf("& al.")!=-1 ) {
926 if (!tmp
.trim().isEmpty()) {
927 teams
.add(tmp
.trim());
930 if(tmp
.indexOf(" et ")!=-1 || tmp
.indexOf("&")!=-1 || tmp
.indexOf(";") !=-1){
931 List
<String
> collteam
= new ArrayList
<String
>();
932 String
[] tmp1
= tmp
.split(" et ");
933 for (String elt
:tmp1
){
934 String tmp2
[] = elt
.split("&");
935 for (String elt2
:tmp2
) {
936 if (!elt2
.trim().isEmpty()) {
937 String tmp3
[] = elt
.split(";");
938 for (String elt3
:tmp3
) {
939 if (!elt3
.isEmpty()){
940 collectors
.add(elt3
.trim());
941 collteam
.add(elt3
.trim());
947 if (collteam
.size()>0) {
948 collectorinteams
.add(new ArrayList
<String
>(new HashSet
<>(collteam
)));
952 if (!tmp
.trim().isEmpty() && !tmp
.toString().trim().equalsIgnoreCase("none")) {
953 collectors
.add(tmp
.trim());
959 List
<String
> collectorsU
= new ArrayList
<String
>(new HashSet
<>(collectors
));
960 List
<String
> teamsU
= new ArrayList
<String
>(new HashSet
<>(teams
));
963 //existing teams in DB
964 Map
<String
,Team
> titleCacheTeam
= new HashMap
<>();
965 List
<UuidAndTitleCache
<Team
>> hiberTeam
= getAgentService().getUuidAndTitleCache(Team
.class, null, null);
967 Set
<UUID
> uuids
= new HashSet
<>();
968 for (UuidAndTitleCache
<Team
> hibernateT
:hiberTeam
){
969 uuids
.add(hibernateT
.getUuid());
971 if (!uuids
.isEmpty()){
972 List
<AgentBase
> existingTeams
= getAgentService().find(uuids
);
973 for (AgentBase
<?
> existingP
:existingTeams
){
974 titleCacheTeam
.put(existingP
.getTitleCache(),(Team
) existingP
);
978 Map
<String
,UUID
> teamMap
= new HashMap
<>();
979 for (UuidAndTitleCache
<Team
> uuidt
:hiberTeam
){
980 teamMap
.put(uuidt
.getTitleCache(), uuidt
.getUuid());
983 //existing persons in DB
984 List
<UuidAndTitleCache
<Person
>> hiberPersons
= getAgentService().getUuidAndTitleCache(Person
.class, null, null);
985 Map
<String
,Person
> titleCachePerson
= new HashMap
<>();
986 uuids
= new HashSet
<UUID
>();
987 for (UuidAndTitleCache
<Person
> hibernateP
:hiberPersons
){
988 uuids
.add(hibernateP
.getUuid());
991 if (!uuids
.isEmpty()){
992 List
<AgentBase
> existingPersons
= getAgentService().find(uuids
);
993 for (AgentBase
<?
> existingP
:existingPersons
){
994 titleCachePerson
.put(existingP
.getTitleCache(),CdmBase
.deproxy(existingP
, Person
.class));
998 Map
<String
,UUID
> personMap
= new HashMap
<String
, UUID
>();
999 for (UuidAndTitleCache
<Person
> person
:hiberPersons
){
1000 personMap
.put(person
.getTitleCache(), person
.getUuid());
1003 java
.util
.Collection
<AgentBase
> personsToAdd
= new ArrayList
<>();
1004 java
.util
.Collection
<AgentBase
> teamsToAdd
= new ArrayList
<>();
1006 for (String collector
:collectorsU
){
1007 Person p
= Person
.NewInstance();
1008 p
.setTitleCache(collector
,true);
1009 if (!personMap
.containsKey(p
.getTitleCache())){
1010 personsToAdd
.add(p
);
1013 for (String team
:teamsU
){
1014 Team p
= Team
.NewInstance();
1015 p
.setTitleCache(team
,true);
1016 if (!teamMap
.containsKey(p
.getTitleCache())){
1020 Map
<UUID
, AgentBase
> uuuidPerson
= getAgentService().save(personsToAdd
);
1021 for (UUID u
:uuuidPerson
.keySet()){
1022 titleCachePerson
.put(uuuidPerson
.get(u
).getTitleCache(),CdmBase
.deproxy(uuuidPerson
.get(u
), Person
.class) );
1026 Map
<String
,Integer
>teamdone
= new HashMap
<String
, Integer
>();
1027 for (List
<String
> collteam
: collectorinteams
){
1028 if (!teamdone
.containsKey(StringUtils
.join(collteam
.toArray(),"-"))){
1029 Team team
= new Team();
1031 for (String collector
:collteam
){
1032 ptmp
= Person
.NewInstance();
1033 ptmp
.setTitleCache(collector
,true);
1034 Person p2
= titleCachePerson
.get(ptmp
.getTitleCache());
1035 team
.addTeamMember(p2
);
1039 teamsToAdd
.add(team
);
1041 teamdone
.put(StringUtils
.join(collteam
.toArray(),"-"),0);
1045 Map
<UUID
, AgentBase
> uuuidTeam
= getAgentService().save(teamsToAdd
);
1047 for (UUID u
:uuuidTeam
.keySet()){
1048 titleCacheTeam
.put(uuuidTeam
.get(u
).getTitleCache(), (Team
) uuuidTeam
.get(u
) );
1051 state
.getConfig().setTeams(titleCacheTeam
);
1052 state
.getConfig().setPersons(titleCachePerson
);
1055 private boolean askQuestion(String question
){
1056 Scanner scan
= new Scanner(System
.in
);
1057 System
.out
.println(question
);
1058 int index
= scan
.nextInt();
1067 protected boolean doCheck(SpecimenSynthesysExcelImportState state
) {
1068 logger
.warn("Validation not yet implemented for " + getClass().getSimpleName());