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.
10 package eu
.etaxonomy
.cdm
.io
.specimen
.excel
.in
;
12 import java
.io
.FileNotFoundException
;
13 import java
.net
.MalformedURLException
;
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
;
21 import java
.util
.Scanner
;
23 import java
.util
.UUID
;
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
;
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
.NomenclaturalCode
;
52 import eu
.etaxonomy
.cdm
.model
.name
.TaxonName
;
53 import eu
.etaxonomy
.cdm
.model
.name
.TaxonNameFactory
;
54 import eu
.etaxonomy
.cdm
.model
.occurrence
.Collection
;
55 import eu
.etaxonomy
.cdm
.model
.occurrence
.DerivedUnit
;
56 import eu
.etaxonomy
.cdm
.model
.occurrence
.DeterminationEvent
;
57 import eu
.etaxonomy
.cdm
.model
.occurrence
.GatheringEvent
;
58 import eu
.etaxonomy
.cdm
.model
.occurrence
.SpecimenOrObservationBase
;
59 import eu
.etaxonomy
.cdm
.model
.occurrence
.SpecimenOrObservationType
;
60 import eu
.etaxonomy
.cdm
.model
.reference
.Reference
;
61 import eu
.etaxonomy
.cdm
.model
.reference
.ReferenceFactory
;
62 import eu
.etaxonomy
.cdm
.model
.taxon
.Classification
;
63 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
64 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
65 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonNode
;
66 import eu
.etaxonomy
.cdm
.persistence
.dto
.UuidAndTitleCache
;
67 import eu
.etaxonomy
.cdm
.strategy
.parser
.NonViralNameParserImpl
;
68 import eu
.etaxonomy
.cdm
.strategy
.parser
.TimePeriodParser
;
77 public class SpecimenSythesysExcelImport
extends CdmImportBase
<SpecimenSynthesysExcelImportConfigurator
, SpecimenSynthesysExcelImportState
>
78 implements ICdmIO
<SpecimenSynthesysExcelImportState
> {
80 private static final Logger logger
= Logger
.getLogger(SpecimenSythesysExcelImport
.class);
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
<String
>();
114 protected ArrayList
<String
> multimediaObjects
= new ArrayList
<String
>();
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
> {
132 private static final long serialVersionUID
= -6230407405666753405L;
134 @SuppressWarnings("unchecked")
136 public V
get(Object key
) {
138 if (containsKey(key
)) {
143 if (a
==null || a
.toString().equalsIgnoreCase("none")) {
152 * getClassification : get the classification declared in the ImportState
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
);
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
);
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
);
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
);
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
);
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());
213 getClassificationService().saveOrUpdate(classification
);
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
224 private void refreshTransaction(){
225 commitTransaction(tx
);
226 tx
= startTransaction();
227 ref
= getReferenceService().find(ref
.getUuid());
228 classification
= getClassificationService().find(classification
.getUuid());
230 derivedUnitBase
= (DerivedUnit
) getOccurrenceService().find(derivedUnitBase
.getUuid());
232 //logger.warn("derivedunit up to date or not created yet");
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
241 // private void refreshTransac(){
242 // commitTransaction(tx);
243 // tx = startTransaction();
246 * Store the unit's properties into variables
247 * @param unit: the hashmap containing the splitted Excel line (Key=column name, value=value)
249 private void setUnitPropertiesExcel(MyHashMap
<String
,String
> unit
, String defaultAuthor
){
250 multimediaObjects
= new ArrayList
<String
>();
251 identificationList
= new ArrayList
<String
>();
255 String author
= unit
.get("author");
256 if (author
.isEmpty() && !defaultAuthor
.isEmpty()) {
257 author
=defaultAuthor
;
259 String taxonName
= unit
.get("taxonName");
261 institutionCode
= unit
.get("institution");
262 collectionCode
= unit
.get("collection");
263 unitID
= unit
.get("unitID");
264 recordBasis
= unit
.get("recordBasis");
266 accessionNumber
= null;
268 try {longitude
= Double
.valueOf(unit
.get("longitude"));
269 } catch (Exception e
) {longitude
= 0.0;}
271 try {latitude
= Double
.valueOf(unit
.get("latitude"));
272 } catch (Exception e
) {latitude
= 0.0;}
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
;
282 if (!habitat
.isEmpty()){
283 locality
+=" (Habitat: "+habitat
+")";
286 fieldNumber
= unit
.get("field number");
288 String url
=unit
.get("url");
289 if (!url
.isEmpty()) {
290 multimediaObjects
.add(url
);
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
;
300 gatheringAgent
= coll
;
304 if(!taxonName
.contains(author
)) {
305 identificationList
.add(taxonName
+" "+author
);
307 identificationList
.add(taxonName
);
310 gatheringYear
= unit
.get("year");
311 gatheringMonth
= unit
.get("month");
312 gatheringDay
= unit
.get("day");
313 gatheringDate
= unit
.get("date");
315 gatheringNotes
= unit
.get("eventRemarks");
316 originalsource
= unit
.get("originalsource");
317 identifier
= unit
.get("identifier");
321 private Institution
getInstitution(SpecimenSynthesysExcelImportConfigurator config
){
322 Institution institution
;
323 List
<Institution
> institutions
;
325 institutions
= getAgentService().searchInstitutionByCode(institutionCode
);
327 institutions
=new ArrayList
<Institution
>();
329 if (institutions
.size() ==0 || !config
.getReUseExistingMetadata()){
330 logger
.debug("Institution (agent) unknown or not allowed to reuse existing metadata");
332 institution
= Institution
.NewInstance();
333 institution
.setCode(institutionCode
);
334 getAgentService().saveOrUpdate(institution
);
337 logger
.debug("Institution (agent) already in the db");
338 institution
= institutions
.get(0);
340 return CdmBase
.deproxy(institution
, Institution
.class);
344 * Look if the Collection does already exists
345 * @param collectionCode: a string
346 * @param institution: the current Institution
348 * @return the Collection (existing or new)
350 private Collection
getCollection(Institution institution
, SpecimenSynthesysExcelImportConfigurator config
){
351 Collection collection
=null;
352 List
<Collection
> collections
;
354 collections
= getCollectionService().searchByCode(collectionCode
);
356 collections
=new ArrayList
<Collection
>();
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
);
367 boolean collectionFound
=false;
368 for (int i
=0; i
<collections
.size(); i
++){
369 collection
= collections
.get(i
);
371 if (collection
.getInstitute().getCode().equalsIgnoreCase(institution
.getCode())){
372 //found a collection with the same code and the same institution
373 collectionFound
=true;
375 } catch (NullPointerException e
) {}
377 if (!collectionFound
){
378 collection
= Collection
.NewInstance();
379 collection
.setCode(collectionCode
);
380 collection
.setCodeStandard("GBIF");
381 collection
.setInstitute(institution
);
391 * @param derivedThing
394 private void setTaxonName(SpecimenSynthesysExcelImportConfigurator config
){
395 TaxonName taxonName
= null;
398 String scientificName
="";
399 boolean preferredFlag
=false;
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) {
413 scientificName
= fullScientificNameString
.trim();
416 if (fullScientificNameString
.indexOf("_code_") != -1){
417 nomenclatureCode
= fullScientificNameString
.split("_code_")[1].trim();
420 if (config
.getDoReUseTaxon()){
421 List
<TaxonBase
> c
= null;
423 Taxon cc
= getTaxonService().findBestMatchingTaxon(scientificName
);
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()){
429 getTaxonService().saveOrUpdate(cc
);
435 c
= getTaxonService().searchTaxaByName(scientificName
, ref
);
436 for (TaxonBase
<?
> b
: c
) {
440 } catch (Exception e
) {
441 logger
.info("Searchtaxabyname failed" + e
);
446 if (!config
.getDoReUseTaxon() || taxon
== null){
448 logger
.info("create new taxonName instance");
450 if (config
.getDoAutomaticParsing()){
451 taxonName
= parseScientificName(scientificName
);
454 taxonName
= TaxonNameFactory
.NewNonViralInstance(null);
455 taxonName
.setTitleCache(scientificName
, true);
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
);
467 DeterminationEvent determinationEvent
= DeterminationEvent
.NewInstance();
468 determinationEvent
.setTaxon(getTaxonService().find(taxon
.getUuid()));
469 determinationEvent
.setPreferredFlag(preferredFlag
);
471 determinationEvent
.setIdentifiedUnit(derivedUnitBase
);
472 if (!identifier
.isEmpty()){
473 Person p
= Person
.NewInstance();
474 p
.setTitleCache(identifier
, true);
475 determinationEvent
.setActor(p
);
477 derivedUnitBase
.addDetermination(determinationEvent
);
479 makeIndividualsAssociation(taxon
,determinationEvent
,config
);
481 getOccurrenceService().saveOrUpdate(derivedUnitBase
);
492 private Taxon
addTaxonNode(Taxon taxon
, SpecimenSynthesysExcelImportConfigurator config
) {
494 logger
.info("link taxon to a taxonNode");
496 boolean exist
= false;
497 for (TaxonNode p
: classification
.getAllNodes()){
498 if(p
.getTaxon().equals(taxon
)) {
503 taxon
= (Taxon
) getTaxonService().find(taxon
.getUuid());
504 classification
.addChildTaxon(taxon
, ref
, null);
505 getClassificationService().saveOrUpdate(classification
);
506 // refreshTransaction();
508 return (Taxon
) getTaxonService().find(taxon
.getUuid());
511 private TaxonName
parseScientificName(String scientificName
){
513 logger
.debug("in parseScientificName");
515 NonViralNameParserImpl nvnpi
= NonViralNameParserImpl
.NewInstance();
516 TaxonName taxonName
= null;
517 boolean problem
=false;
520 logger
.debug("nomenclature: "+nomenclatureCode
);
523 if(nomenclatureCode
== null){
524 taxonName
= TaxonNameFactory
.NewNonViralInstance(null);
525 taxonName
.setTitleCache(scientificName
, true);
529 if (nomenclatureCode
.toString().equals("Zoological")){
530 taxonName
= (TaxonName
)nvnpi
.parseFullName(scientificName
,NomenclaturalCode
.ICZN
,null);
531 if (taxonName
.hasProblem()) {
535 if (nomenclatureCode
.toString().equals("Botanical")){
536 taxonName
= (TaxonName
)nvnpi
.parseFullName(scientificName
,NomenclaturalCode
.ICNAFP
,null);
537 if (taxonName
.hasProblem()) {
540 if (nomenclatureCode
.toString().equals("Bacterial")){
541 taxonName
= (TaxonName
)nvnpi
.parseFullName(scientificName
,NomenclaturalCode
.ICNB
, null);
542 if (taxonName
.hasProblem()) {
546 if (nomenclatureCode
.toString().equals("Cultivar")){
547 taxonName
= (TaxonName
)nvnpi
.parseFullName(scientificName
,NomenclaturalCode
.ICNCP
, null);
548 if (taxonName
.hasProblem()) {
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");
557 //TODO: parsing of ViralNames?
559 taxonName
= TaxonNameFactory
.NewNonViralInstance(null);
560 taxonName
.setTitleCache(scientificName
, true);
566 private DerivedUnitFacade
getFacade() {
567 // logger.info("GETFACADE");
569 * SPECIMEN OR OBSERVATION OR LIVING
571 // DerivedUnit derivedThing = null;
572 SpecimenOrObservationType type
= null;
575 if (recordBasis
!= null) {
576 String rec
= recordBasis
.toLowerCase();
577 if (rec
.contains("specimen") || rec
.startsWith("s")) {// specimen
578 type
= SpecimenOrObservationType
.PreservedSpecimen
;
580 if (rec
.contains("observat") || rec
.startsWith("o")) {
581 type
= SpecimenOrObservationType
.Observation
;
583 if (rec
.contains("fossil") || rec
.startsWith("f") ){
584 type
= SpecimenOrObservationType
.Fossil
;
587 if (rec
.contains("living") || rec
.startsWith("l")) {
588 type
= SpecimenOrObservationType
.LivingSpecimen
;
592 logger
.info("The basis of record does not seem to be known: " + recordBasis
);
594 type
= SpecimenOrObservationType
.DerivedUnit
;
597 logger
.info("The basis of record is null");
598 type
= SpecimenOrObservationType
.DerivedUnit
;
600 DerivedUnitFacade derivedUnitFacade
= DerivedUnitFacade
.NewInstance(type
);
601 return derivedUnitFacade
;
605 * Store the unit with it's Gathering informations in the CDM
607 public boolean start(SpecimenSynthesysExcelImportConfigurator config
){
608 boolean result
= true;
610 // refreshTransaction();
614 * SPECIMEN OR OBSERVATION OR LIVING
616 DerivedUnitFacade derivedUnitFacade
= getFacade();
617 derivedUnitBase
= derivedUnitFacade
.innerDerivedUnit();
619 //set catalogue number (unitID)
620 derivedUnitFacade
.setCatalogNumber(unitID
);
621 derivedUnitFacade
.setAccessionNumber(accessionNumber
);
623 if (!originalsource
.isEmpty()){
624 Reference reference
= ReferenceFactory
.newGeneric();
625 reference
.setTitleCache(originalsource
, true);
626 derivedUnitBase
.addSource(OriginalSourceType
.Import
, originalsource
, "", reference
, "");
628 derivedUnitBase
.addSource(OriginalSourceType
.Import
, unitID
,"",ref
,ref
.getCitation());
631 * INSTITUTION & COLLECTION
634 if (!institutionCode
.isEmpty()){
635 Institution institution
= getInstitution(config
);
637 if (!collectionCode
.isEmpty()){
638 Collection collection
= getCollection(institution
, config
);
639 //link specimen & collection
640 derivedUnitFacade
.setCollection(collection
);
648 UnitsGatheringEvent unitsGatheringEvent
= new UnitsGatheringEvent(getTermService(), locality
, languageIso
,
649 longitude
, latitude
, gatheringAgent
, gatheringTeam
,config
);
651 UnitsGatheringArea unitsGatheringArea
= new UnitsGatheringArea();
652 unitsGatheringArea
.useTDWGareas(this.useTDWGarea
);
653 // unitsGatheringArea.setConfig(config, getOccurrenceService(),getTermService());
654 unitsGatheringArea
.setParams(isocountry
, country
, config
, getTermService(), getOccurrenceService());
655 DefinedTermBase areaCountry
=unitsGatheringArea
.getCountry();
659 // copy gathering event to facade
660 GatheringEvent gatheringEvent
= unitsGatheringEvent
.getGatheringEvent();
661 //join gatheringEvent to fieldObservation
662 derivedUnitFacade
.setGatheringEvent(gatheringEvent
);
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
);
671 if (gatheringNotes
!= null && !gatheringNotes
.isEmpty()) {
672 derivedUnitFacade
.setFieldNotes(gatheringNotes
);
677 * merge AND STORE DATA
679 // getTermService().saveOrUpdate(areaCountry);// TODO save area sooner
680 getTermService().saveLanguageData(unitsGatheringEvent
.getLocality());
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
));
695 unitsGatheringEvent
.setGatheringDate(tp
);
699 if (!gatheringDate
.isEmpty()){
700 TimePeriod tp
= TimePeriodParser
.parseString(gatheringDate
);
701 unitsGatheringEvent
.setGatheringDate(tp
);
707 derivedUnitFacade
.setFieldNumber(fieldNumber
);
709 //add Multimedia URLs
710 if(multimediaObjects
.size()>0){
711 for (String multimediaObject
: multimediaObjects
) {
714 media
= getImageMedia(multimediaObject
, READ_MEDIA_DATA
);
715 derivedUnitFacade
.addDerivedUnitMedia(media
);
716 } catch (MalformedURLException e
) {
717 // TODO Auto-generated catch block
723 getOccurrenceService().saveOrUpdate(derivedUnitBase
);
725 setTaxonName(config
);
727 // refreshTransaction();
729 logger
.info("saved new specimen ...");
732 } catch (Exception e
) {
733 logger
.warn("Error when reading record!!");
738 logger
.info("commit done");
745 * Store the unit with it's Gathering informations in the CDM
747 public boolean resetCollectionInstitution(SpecimenSynthesysExcelImportConfigurator config
,List
<SpecimenOrObservationBase
> specimenOrObs
){
748 boolean result
= true;
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);
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");
764 Institution institution
= getInstitution(config
);
766 Collection col
= getCollection(institution
, config
);
767 getCollectionService().saveOrUpdate(col
);
768 derivedUnit
.setCollection(col
);
769 getOccurrenceService().saveOrUpdate(derivedUnit
);
774 if(specimen
.isInstanceOf(IndividualsAssociation
.class)) {
775 System
.out
.println("Indivi assoc");
782 private Feature
makeFeature(SpecimenOrObservationBase
<?
> unit
) {
786 SpecimenOrObservationType type
= unit
.getRecordBasis();
788 if (type
.isFeatureObservation()){
789 return Feature
.OBSERVATION();
790 }else if (type
.isPreservedSpecimen() ||
791 type
== SpecimenOrObservationType
.LivingSpecimen
||
792 type
== SpecimenOrObservationType
.OtherSpecimen
794 return Feature
.SPECIMEN();
795 }else if (type
== SpecimenOrObservationType
.Unknown
||
796 type
== SpecimenOrObservationType
.DerivedUnit
798 return Feature
.INDIVIDUALS_ASSOCIATION();
801 logger
.warn("No feature defined for derived unit class: "
802 + unit
.getClass().getSimpleName());
807 private void makeIndividualsAssociation(Taxon taxon
, DeterminationEvent determinationEvent
, SpecimenSynthesysExcelImportConfigurator config
) {
809 // taxon = (Taxon) getTaxonService().find(taxon.getUuid());
811 // catch(Exception e){
812 // //logger.info("taxon uptodate");
815 TaxonDescription taxonDescription
=null;
816 if (taxon
.getTitleCache().contains("Chenopodium vulvaria L.")) {
817 taxonDescription
= (TaxonDescription
) getDescriptionService().find(UUID
.fromString("a60074e7-979b-41fd-ad4d-d391db474ac4"));
819 if(!taxon
.getTitleCache().contains("Chenopodium vulvaria L.") || taxonDescription
==null) {
820 taxonDescription
= getTaxonDescription(taxon
, ref
, false, true);
821 taxonDescription
.setTitleCache(ref
.getTitleCache(), true);
825 taxon
.addDescription(taxonDescription
);
827 IndividualsAssociation indAssociation
= IndividualsAssociation
.NewInstance();
828 Feature feature
= makeFeature(derivedUnitBase
);
829 indAssociation
.setAssociatedSpecimenOrObservation(derivedUnitBase
);
830 indAssociation
.setFeature(feature
);
832 for (Reference citation
: determinationEvent
.getReferences()) {
833 indAssociation
.addSource(DescriptionElementSource
.NewInstance(OriginalSourceType
.Import
, null, null, citation
, null));
835 indAssociation
.addSource(OriginalSourceType
.Import
, null,null,config
.getDataReference(),null);
837 taxonDescription
.addElement(indAssociation
);
839 getDescriptionService().saveOrUpdate(taxonDescription
);
840 getTaxonService().saveOrUpdate(taxon
);
844 protected boolean isIgnore(SpecimenSynthesysExcelImportState state
) {
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.");
857 tx
= startTransaction();
859 ref
= state
.getConfig().getTaxonReference();
861 ref
= state
.getConfig().getSourceReference();
863 AgentBase
<?
> agent
= ref
.getAuthorship();
865 if (agent
.getClass().equals(Team
.class)){
866 for (Person p
: ((Team
) agent
).getTeamMembers()){
867 getAgentService().saveOrUpdate(p
);
870 if (agent
.getClass().equals(Person
.class)){
871 getAgentService().saveOrUpdate(agent
);
874 getReferenceService().saveOrUpdate(ref
);
875 setClassification(state
);
877 refreshTransaction();
879 URI source
= state
.getConfig().getSource();
880 ArrayList
<HashMap
<String
,String
>> unitsList
= null;
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
);
890 if (unitsList
!= null){
891 //load collectors in the database
892 if (!state
.getConfig().isDebugInstitutionOnly()) {
893 prepareCollectors(unitsList
,state
);
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
);
902 specimenOrObs
= getOccurrenceService().listByAssociatedTaxon(null, null, taxon
, null, null, null, null, null);
904 HashMap
<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++){
909 logger
.info("NbUnit prepared: "+i
);
910 refreshTransaction();
912 unit
= unitsList
.get(i
);
913 myunit
=new MyHashMap
<String
, String
>();
914 for (String key
:unit
.keySet()) {
915 myunit
.put(key
, unit
.get(key
));
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
);
923 success
&= start(state
.getConfig());
927 if (success
== false){
928 state
.setUnsuccessfull();
930 commitTransaction(tx
);
939 private void prepareCollectors(ArrayList
<HashMap
<String
, String
>> unitsList
, SpecimenSynthesysExcelImportState state
) {
940 System
.out
.println("PREPARE COLLECTORS");
941 List
<String
> collectors
= new ArrayList
<String
>();
942 List
<String
> teams
= new ArrayList
<String
>();
943 List
<List
<String
>> collectorinteams
= new ArrayList
<List
<String
>>();
945 for (HashMap
<String
,String
> unit
: unitsList
){
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());
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());
971 if (collteam
.size()>0) {
972 collectorinteams
.add(new ArrayList
<String
>(new HashSet
<String
>(collteam
)));
976 if (!tmp
.trim().isEmpty() && !tmp
.toString().trim().equalsIgnoreCase("none")) {
977 collectors
.add(tmp
.trim());
983 List
<String
> collectorsU
= new ArrayList
<String
>(new HashSet
<String
>(collectors
));
984 List
<String
> teamsU
= new ArrayList
<String
>(new HashSet
<String
>(teams
));
987 //existing teams in DB
988 Map
<String
,Team
> titleCacheTeam
= new HashMap
<String
, Team
>();
989 List
<UuidAndTitleCache
<Team
>> hiberTeam
= getAgentService().getTeamUuidAndTitleCache();
991 Set
<UUID
> uuids
= new HashSet
<UUID
>();
992 for (UuidAndTitleCache
<Team
> hibernateT
:hiberTeam
){
993 uuids
.add(hibernateT
.getUuid());
995 if (!uuids
.isEmpty()){
996 List
<AgentBase
> existingTeams
= getAgentService().find(uuids
);
997 for (AgentBase
<?
> existingP
:existingTeams
){
998 titleCacheTeam
.put(existingP
.getTitleCache(),(Team
) existingP
);
1003 Map
<String
,UUID
> teamMap
= new HashMap
<String
, UUID
>();
1004 for (UuidAndTitleCache
<Team
> uuidt
:hiberTeam
){
1005 teamMap
.put(uuidt
.getTitleCache(), uuidt
.getUuid());
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());
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));
1023 Map
<String
,UUID
> personMap
= new HashMap
<String
, UUID
>();
1024 for (UuidAndTitleCache
<Person
> person
:hiberPersons
){
1025 personMap
.put(person
.getTitleCache(), person
.getUuid());
1028 java
.util
.Collection
<AgentBase
> personsToAdd
= new ArrayList
<AgentBase
>();
1029 java
.util
.Collection
<AgentBase
> teamsToAdd
= new ArrayList
<AgentBase
>();
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
);
1038 for (String team
:teamsU
){
1039 Team p
= Team
.NewInstance();
1040 p
.setTitleCache(team
,true);
1041 if (!teamMap
.containsKey(p
.getTitleCache())){
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) );
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();
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
);
1065 teamsToAdd
.add(team
);
1067 teamdone
.put(StringUtils
.join(collteam
.toArray(),"-"),0);
1072 Map
<UUID
, AgentBase
> uuuidTeam
= getAgentService().save(teamsToAdd
);
1074 for (UUID u
:uuuidTeam
.keySet()){
1075 titleCacheTeam
.put(uuuidTeam
.get(u
).getTitleCache(), (Team
) uuuidTeam
.get(u
) );
1078 state
.getConfig().setTeams(titleCacheTeam
);
1079 state
.getConfig().setPersons(titleCachePerson
);
1082 private boolean askQuestion(String question
){
1083 Scanner scan
= new Scanner(System
.in
);
1084 System
.out
.println(question
);
1085 int index
= scan
.nextInt();
1095 protected boolean doCheck(SpecimenSynthesysExcelImportState state
) {
1096 logger
.warn("Validation not yet implemented for " + getClass().getSimpleName());