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
.apache
.poi
.hssf
.usermodel
.HSSFWorkbook
;
28 import org
.springframework
.stereotype
.Component
;
29 import org
.springframework
.transaction
.TransactionStatus
;
31 import eu
.etaxonomy
.cdm
.api
.facade
.DerivedUnitFacade
;
32 import eu
.etaxonomy
.cdm
.api
.facade
.DerivedUnitFacade
.DerivedUnitType
;
33 import eu
.etaxonomy
.cdm
.common
.ExcelUtils
;
34 import eu
.etaxonomy
.cdm
.io
.common
.CdmImportBase
;
35 import eu
.etaxonomy
.cdm
.io
.common
.ICdmIO
;
36 import eu
.etaxonomy
.cdm
.io
.specimen
.UnitsGatheringArea
;
37 import eu
.etaxonomy
.cdm
.io
.specimen
.UnitsGatheringEvent
;
38 import eu
.etaxonomy
.cdm
.model
.agent
.AgentBase
;
39 import eu
.etaxonomy
.cdm
.model
.agent
.Institution
;
40 import eu
.etaxonomy
.cdm
.model
.agent
.Person
;
41 import eu
.etaxonomy
.cdm
.model
.agent
.Team
;
42 import eu
.etaxonomy
.cdm
.model
.common
.DescriptionElementSource
;
43 import eu
.etaxonomy
.cdm
.model
.common
.Language
;
44 import eu
.etaxonomy
.cdm
.model
.common
.OriginalSourceType
;
45 import eu
.etaxonomy
.cdm
.model
.common
.TimePeriod
;
46 import eu
.etaxonomy
.cdm
.model
.common
.UuidAndTitleCache
;
47 import eu
.etaxonomy
.cdm
.model
.description
.Feature
;
48 import eu
.etaxonomy
.cdm
.model
.description
.IndividualsAssociation
;
49 import eu
.etaxonomy
.cdm
.model
.description
.TaxonDescription
;
50 import eu
.etaxonomy
.cdm
.model
.location
.NamedArea
;
51 import eu
.etaxonomy
.cdm
.model
.media
.Media
;
52 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalCode
;
53 import eu
.etaxonomy
.cdm
.model
.name
.NonViralName
;
54 import eu
.etaxonomy
.cdm
.model
.name
.Rank
;
55 import eu
.etaxonomy
.cdm
.model
.occurrence
.Collection
;
56 import eu
.etaxonomy
.cdm
.model
.occurrence
.DerivedUnit
;
57 import eu
.etaxonomy
.cdm
.model
.occurrence
.DerivedUnitBase
;
58 import eu
.etaxonomy
.cdm
.model
.occurrence
.DeterminationEvent
;
59 import eu
.etaxonomy
.cdm
.model
.occurrence
.FieldObservation
;
60 import eu
.etaxonomy
.cdm
.model
.occurrence
.Fossil
;
61 import eu
.etaxonomy
.cdm
.model
.occurrence
.GatheringEvent
;
62 import eu
.etaxonomy
.cdm
.model
.occurrence
.LivingBeing
;
63 import eu
.etaxonomy
.cdm
.model
.occurrence
.Observation
;
64 import eu
.etaxonomy
.cdm
.model
.occurrence
.Specimen
;
65 import eu
.etaxonomy
.cdm
.model
.occurrence
.SpecimenOrObservationBase
;
66 import eu
.etaxonomy
.cdm
.model
.reference
.Reference
;
67 import eu
.etaxonomy
.cdm
.model
.reference
.ReferenceFactory
;
68 import eu
.etaxonomy
.cdm
.model
.taxon
.Classification
;
69 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
70 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
71 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonNode
;
72 import eu
.etaxonomy
.cdm
.strategy
.parser
.NonViralNameParserImpl
;
84 public class SpecimenSythesysExcelImport
extends CdmImportBase
<SpecimenSynthesysExcelImportConfigurator
, SpecimenSynthesysExcelImportState
> implements ICdmIO
<SpecimenSynthesysExcelImportState
> {
86 private static final Logger logger
= Logger
.getLogger(SpecimenSythesysExcelImport
.class);
88 protected String fullScientificNameString
;
89 protected String nomenclatureCode
;
90 protected String institutionCode
;
91 protected String collectionCode
;
92 protected String unitID
;
93 protected String recordBasis
;
94 protected String accessionNumber
;
95 protected String fieldNumber
;
96 protected Double longitude
;
97 protected Double latitude
;
98 protected String locality
;
99 protected String languageIso
= null;
100 protected String country
;
101 protected String isocountry
;
103 protected int altitude
;
104 protected String gatheringYear
;
105 protected String gatheringMonth
;
106 protected String gatheringDay
;
107 protected String gatheringDate
;
108 protected String gatheringTeam
;
109 protected String gatheringAgent
;
110 protected String originalsource
;
112 private DerivedUnitBase derivedUnitBase
;
113 private Reference
<?
> ref
= null;
114 private TransactionStatus tx
;
115 private Classification classification
= null;
117 protected ArrayList
<String
> identificationList
= new ArrayList
<String
>();
118 protected ArrayList
<String
> multimediaObjects
= new ArrayList
<String
>();
119 private boolean keepAtomisedDate
=true;
121 boolean DEBUG
=false;
123 protected HSSFWorkbook hssfworkbook
= null;
125 public SpecimenSythesysExcelImport() {
130 * private HashMap that handle null values (missing keys)
131 * return empty string instead of null
133 public class MyHashMap
<K
,V
> extends HashMap
<K
,V
> {
134 private static final long serialVersionUID
= -6230407405666753405L;
136 @SuppressWarnings("unchecked")
138 public V
get(Object key
) {
140 if (containsKey(key
)) {
145 if (a
==null || a
.toString().equalsIgnoreCase("none")) {
154 * getClassification : get the classification declared in the ImportState
159 private void setClassification(SpecimenSynthesysExcelImportState state
) {
160 if (classification
== null){
161 if (state
.getConfig().getClassificationName()!=null && state
.getConfig().getClassificationName().equalsIgnoreCase("chenopodium")) {
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
);
170 String name
= state
.getConfig().getClassificationName();
171 classification
= Classification
.NewInstance(name
, ref
, Language
.DEFAULT());
172 if (state
.getConfig().getClassificationUuid() != null) {
173 classification
.setUuid(state
.getConfig().getClassificationUuid());
175 getClassificationService().saveOrUpdate(classification
);
182 * refresh the hibernate transaction :
183 * - commit the current queries
184 * - get the reference and the classification and the derivedUnitBase back from the hibernate session
186 private void refreshTransaction(){
187 commitTransaction(tx
);
188 tx
= startTransaction();
189 ref
= getReferenceService().find(ref
.getUuid());
190 classification
= getClassificationService().find(classification
.getUuid());
191 if (derivedUnitBase
!= null){
192 derivedUnitBase
= (DerivedUnitBase
) getOccurrenceService().find(derivedUnitBase
.getUuid());
197 * Store the unit's properties into variables
198 * @param unit: the hashmap containing the splitted Excel line (Key=column name, value=value)
200 private void setUnitPropertiesExcel(MyHashMap
<String
,String
> unit
, String defaultAuthor
){
201 multimediaObjects
= new ArrayList
<String
>();
202 identificationList
= new ArrayList
<String
>();
206 String author
= unit
.get("author");
207 if (author
.isEmpty() && !defaultAuthor
.isEmpty()) {
208 author
=defaultAuthor
;
210 String taxonName
= unit
.get("taxonName");
212 institutionCode
= unit
.get("institution");
213 collectionCode
= unit
.get("collection");
214 unitID
= unit
.get("unitID");
215 recordBasis
= unit
.get("recordBasis");
217 accessionNumber
= null;
219 try {longitude
= Double
.valueOf(unit
.get("longitude"));
220 } catch (Exception e
) {longitude
= 0.0;}
222 try {latitude
= Double
.valueOf(unit
.get("latitude"));
223 } catch (Exception e
) {latitude
= 0.0;}
225 country
= unit
.get("country");
226 isocountry
= unit
.get("isoCountry");
227 locality
= unit
.get("locality");
229 fieldNumber
= unit
.get("field number");
231 String url
=unit
.get("url");
232 if (!url
.isEmpty()) {
233 multimediaObjects
.add(url
);
236 String coll
=unit
.get("collector");
237 if (!coll
.isEmpty()) {
238 if (coll
.indexOf("& al.")!=-1 || coll
.indexOf("et al.") != -1 || coll
.indexOf(" al. ")!=-1 || coll
.indexOf("&") != -1 || coll
.indexOf(" et ") != -1) {
239 gatheringTeam
= coll
;
242 gatheringAgent
= coll
;
246 identificationList
.add(taxonName
+" "+author
);
248 gatheringYear
= unit
.get("year");
249 gatheringMonth
= unit
.get("month");
250 gatheringDay
= unit
.get("day");
251 gatheringDate
= unit
.get("date");
253 originalsource
= unit
.get("originalsource");
257 private Institution
getInstitution(SpecimenSynthesysExcelImportConfigurator config
){
258 Institution institution
;
259 List
<Institution
> institutions
;
261 institutions
= getAgentService().searchInstitutionByCode(institutionCode
);
263 institutions
=new ArrayList
<Institution
>();
265 if (institutions
.size() ==0 || !config
.getReUseExistingMetadata()){
266 logger
.debug("Institution (agent) unknown or not allowed to reuse existing metadata");
268 institution
= Institution
.NewInstance();
269 institution
.setCode(institutionCode
);
272 logger
.debug("Institution (agent) already in the db");
273 institution
= institutions
.get(0);
279 * Look if the Collection does already exists
280 * @param collectionCode: a string
281 * @param institution: the current Institution
283 * @return the Collection (existing or new)
285 private Collection
getCollection(Institution institution
, SpecimenSynthesysExcelImportConfigurator config
){
286 Collection collection
= Collection
.NewInstance();
287 List
<Collection
> collections
;
289 collections
= getCollectionService().searchByCode(collectionCode
);
291 collections
=new ArrayList
<Collection
>();
293 if (collections
.size() ==0 || !config
.getReUseExistingMetadata()){
294 logger
.debug("Collection not found or do not reuse existing metadata "+collectionCode
);
295 //create new collection
296 collection
.setCode(collectionCode
);
297 collection
.setCodeStandard("GBIF");
298 collection
.setInstitute(institution
);
301 boolean collectionFound
=false;
302 for (int i
=0; i
<collections
.size(); i
++){
303 collection
= collections
.get(i
);
305 if (collection
.getInstitute().getCode().equalsIgnoreCase(institution
.getCode())){
306 //found a collection with the same code and the same institution
307 collectionFound
=true;
309 } catch (NullPointerException e
) {}
311 if (!collectionFound
){
312 collection
.setCode(collectionCode
);
313 collection
.setCodeStandard("GBIF");
314 collection
.setInstitute(institution
);
324 * @param derivedThing
327 private void setTaxonNameBase(SpecimenSynthesysExcelImportConfigurator config
){
328 NonViralName
<?
> taxonName
= null;
331 String scientificName
="";
332 boolean preferredFlag
=false;
334 for (int i
= 0; i
< identificationList
.size(); i
++) {
335 String fullScientificNameString
= identificationList
.get(i
);
336 fullScientificNameString
= fullScientificNameString
.replaceAll(" et ", " & ");
337 if (fullScientificNameString
.indexOf("_preferred_") != -1){
338 scientificName
= fullScientificNameString
.split("_preferred_")[0].trim();
339 String pTmp
= fullScientificNameString
.split("_preferred_")[1].split("_code_")[0];
340 if (pTmp
== "1" || pTmp
.toLowerCase().indexOf("true") != -1) {
346 scientificName
= fullScientificNameString
.trim();
349 if (fullScientificNameString
.indexOf("_code_") != -1){
350 nomenclatureCode
= fullScientificNameString
.split("_code_")[1].trim();
353 if (config
.getDoReUseTaxon()){
354 List
<TaxonBase
> c
= null;
356 Taxon cc
= getTaxonService().findBestMatchingTaxon(scientificName
);
358 if ((cc
.getSec() == null || cc
.getSec().toString().isEmpty()) || (cc
.getSec() != null && cc
.getSec().getTitleCache().equalsIgnoreCase(ref
.getTitleCache()))) {
359 if(cc
.getSec() == null || cc
.getSec().toString().isEmpty()){
361 getTaxonService().saveOrUpdate(cc
);
367 c
= getTaxonService().searchTaxaByName(scientificName
, ref
);
368 for (TaxonBase b
: c
) {
372 } catch (Exception e
) {
373 logger
.info("Searchtaxabyname failed" + e
);
378 if (!config
.getDoReUseTaxon() || taxon
== null){
380 logger
.info("create new taxonName instance");
382 if (config
.getDoAutomaticParsing()){
383 taxonName
= parseScientificName(scientificName
);
386 taxonName
= NonViralName
.NewInstance(Rank
.UNKNOWN_RANK());
387 taxonName
.setTitleCache(scientificName
, true);
389 getNameService().save(taxonName
);
390 taxon
= Taxon
.NewInstance(taxonName
, ref
); //sec set null
391 getTaxonService().save(taxon
);
392 // refreshTransaction();
393 taxon
= (Taxon
) getTaxonService().find(taxon
.getUuid());
394 taxon
= addTaxonNode(taxon
, config
);
399 DeterminationEvent determinationEvent
= DeterminationEvent
.NewInstance();
400 determinationEvent
.setTaxon(getTaxonService().find(taxon
.getUuid()));
401 determinationEvent
.setPreferredFlag(preferredFlag
);
403 determinationEvent
.setIdentifiedUnit(derivedUnitBase
);
405 derivedUnitBase
.addDetermination(determinationEvent
);
407 makeIndividualsAssociation(taxon
,determinationEvent
);
409 getOccurrenceService().saveOrUpdate(derivedUnitBase
);
420 private Taxon
addTaxonNode(Taxon taxon
, SpecimenSynthesysExcelImportConfigurator config
) {
422 logger
.info("link taxon to a taxonNode");
424 boolean exist
= false;
425 for (TaxonNode p
: classification
.getAllNodes()){
426 if(p
.getTaxon().equals(taxon
)) {
431 taxon
= (Taxon
) getTaxonService().find(taxon
.getUuid());
432 classification
.addChildTaxon(taxon
, ref
, "", null);
433 getClassificationService().saveOrUpdate(classification
);
434 // refreshTransaction();
436 return (Taxon
) getTaxonService().find(taxon
.getUuid());
439 private NonViralName
<?
> parseScientificName(String scientificName
){
441 logger
.debug("in parseScientificName");
443 NonViralNameParserImpl nvnpi
= NonViralNameParserImpl
.NewInstance();
444 NonViralName
<?
>taxonName
= null;
445 boolean problem
=false;
448 logger
.debug("nomenclature: "+nomenclatureCode
);
451 if(nomenclatureCode
== null){
452 taxonName
= NonViralName
.NewInstance(Rank
.UNKNOWN_RANK());
453 taxonName
.setTitleCache(scientificName
, true);
457 if (nomenclatureCode
.toString().equals("Zoological")){
458 taxonName
= nvnpi
.parseFullName(scientificName
,NomenclaturalCode
.ICZN
,null);
459 if (taxonName
.hasProblem()) {
463 if (nomenclatureCode
.toString().equals("Botanical")){
464 taxonName
= nvnpi
.parseFullName(scientificName
,NomenclaturalCode
.ICNAFP
,null);
465 if (taxonName
.hasProblem()) {
468 if (nomenclatureCode
.toString().equals("Bacterial")){
469 taxonName
= nvnpi
.parseFullName(scientificName
,NomenclaturalCode
.ICNB
, null);
470 if (taxonName
.hasProblem()) {
474 if (nomenclatureCode
.toString().equals("Cultivar")){
475 taxonName
= nvnpi
.parseFullName(scientificName
,NomenclaturalCode
.ICNCP
, null);
476 if (taxonName
.hasProblem()) {
480 // if (nomenclatureCode.toString().equals("Viral")){
481 // ViralName taxonName = (ViralName)nvnpi.parseFullName(scientificName,NomenclaturalCode.ICVCN(), null);
482 // if (taxonName.hasProblem())
483 // System.out.println("pb ICVCN");
485 //TODO: parsing of ViralNames?
487 taxonName
= NonViralName
.NewInstance(Rank
.UNKNOWN_RANK());
488 taxonName
.setTitleCache(scientificName
, true);
494 private DerivedUnitFacade
getFacade() {
495 // logger.info("GETFACADE");
497 * SPECIMEN OR OBSERVATION OR LIVING
499 // DerivedUnitBase derivedThing = null;
500 DerivedUnitType type
= null;
503 if (recordBasis
!= null) {
504 String rec
= recordBasis
.toLowerCase();
505 if (rec
.contains("specimen") || rec
.startsWith("s")) {// specimen
506 type
= DerivedUnitType
.Specimen
;
508 if (rec
.contains("observat") || rec
.startsWith("o")) {
509 type
= DerivedUnitType
.Observation
;
511 if (rec
.contains("fossil") || rec
.startsWith("f") ){
512 type
= DerivedUnitType
.Fossil
;
515 if (rec
.contains("living") || rec
.startsWith("l")) {
516 type
= DerivedUnitType
.LivingBeing
;
520 logger
.info("The basis of record does not seem to be known: " + recordBasis
);
522 type
= DerivedUnitType
.DerivedUnit
;
525 logger
.info("The basis of record is null");
526 type
= DerivedUnitType
.DerivedUnit
;
528 DerivedUnitFacade derivedUnitFacade
= DerivedUnitFacade
.NewInstance(type
);
529 return derivedUnitFacade
;
533 * Store the unit with it's Gathering informations in the CDM
535 public boolean start(SpecimenSynthesysExcelImportConfigurator config
){
536 boolean result
= true;
538 // refreshTransaction();
542 * SPECIMEN OR OBSERVATION OR LIVING
544 DerivedUnitFacade derivedUnitFacade
= getFacade();
545 derivedUnitBase
= derivedUnitFacade
.innerDerivedUnit();
547 //set catalogue number (unitID)
548 derivedUnitFacade
.setCatalogNumber(unitID
);
549 derivedUnitFacade
.setAccessionNumber(accessionNumber
);
551 if (!originalsource
.isEmpty()){
552 Reference
<?
> reference
= ReferenceFactory
.newGeneric();
553 reference
.setTitleCache(originalsource
, true);
554 derivedUnitBase
.addSource(OriginalSourceType
.Unknown
, originalsource
, "", reference
, "");
557 * INSTITUTION & COLLECTION
560 Institution institution
= getInstitution(config
);
562 Collection collection
= getCollection(institution
, config
);
563 //link specimen & collection
564 derivedUnitFacade
.setCollection(collection
);
571 UnitsGatheringEvent unitsGatheringEvent
= new UnitsGatheringEvent(getTermService(), locality
, languageIso
,
572 longitude
, latitude
, gatheringAgent
, gatheringTeam
,config
);
575 UnitsGatheringArea unitsGatheringArea
= new UnitsGatheringArea(isocountry
, country
, this);
576 NamedArea areaCountry
= unitsGatheringArea
.getArea();
580 // copy gathering event to facade
581 GatheringEvent gatheringEvent
= unitsGatheringEvent
.getGatheringEvent();
583 //join gatheringEvent to fieldObservation
584 derivedUnitFacade
.setGatheringEvent(gatheringEvent
);
586 derivedUnitFacade
.setLocality(gatheringEvent
.getLocality());
587 derivedUnitFacade
.setExactLocation(gatheringEvent
.getExactLocation());
588 //derivedUnitFacade.setCollector(gatheringEvent.getCollector());
589 derivedUnitFacade
.setCountry(areaCountry
);
590 derivedUnitFacade
.addCollectingAreas(unitsGatheringArea
.getAreas());
594 * merge AND STORE DATA
596 getTermService().saveOrUpdate(areaCountry
);// TODO save area sooner
597 getTermService().saveLanguageData(unitsGatheringEvent
.getLocality());
602 if (keepAtomisedDate
&& (!gatheringYear
.isEmpty() || !gatheringMonth
.isEmpty() || !gatheringDay
.isEmpty())){
603 Calendar calendar
= Calendar
.getInstance();
604 if (!gatheringYear
.isEmpty()) {
605 TimePeriod tp
= TimePeriod
.NewInstance(Integer
.parseInt(gatheringYear
));
606 if (!gatheringMonth
.isEmpty()) {
607 tp
.setStartMonth(Integer
.parseInt(gatheringMonth
));
608 if (!gatheringDay
.isEmpty()) {
609 tp
.setStartDay(Integer
.parseInt(gatheringDay
));
612 unitsGatheringEvent
.setGatheringDate(tp
);
616 if (!gatheringDate
.isEmpty()){
617 TimePeriod tp
= TimePeriod
.parseString(gatheringDate
);
618 unitsGatheringEvent
.setGatheringDate(tp
);
624 derivedUnitFacade
.setFieldNumber(NB(fieldNumber
));
626 //add Multimedia URLs
627 if(multimediaObjects
.size()>0){
628 for (String multimediaObject
: multimediaObjects
) {
631 media
= getImageMedia(multimediaObject
, READ_MEDIA_DATA
, false);
632 derivedUnitFacade
.addDerivedUnitMedia(media
);
633 } catch (MalformedURLException e
) {
634 // TODO Auto-generated catch block
640 getOccurrenceService().saveOrUpdate(derivedUnitBase
);
642 setTaxonNameBase(config
);
644 // refreshTransaction();
646 logger
.info("saved new specimen ...");
649 } catch (Exception e
) {
650 logger
.warn("Error when reading record!!");
655 logger
.info("commit done");
662 private Feature
makeFeature(SpecimenOrObservationBase unit
) {
663 if (unit
.isInstanceOf(DerivedUnit
.class)) {
664 return Feature
.INDIVIDUALS_ASSOCIATION();
665 } else if (unit
.isInstanceOf(FieldObservation
.class)
666 || unit
.isInstanceOf(Observation
.class)) {
667 return Feature
.OBSERVATION();
668 } else if (unit
.isInstanceOf(Fossil
.class)
669 || unit
.isInstanceOf(LivingBeing
.class)
670 || unit
.isInstanceOf(Specimen
.class)) {
671 return Feature
.SPECIMEN();
674 logger
.warn("No feature defined for derived unit class: "
675 + unit
.getClass().getSimpleName());
680 private void makeIndividualsAssociation(Taxon taxon
, DeterminationEvent determinationEvent
) {
682 // taxon = (Taxon) getTaxonService().find(taxon.getUuid());
684 // catch(Exception e){
685 // //logger.info("taxon uptodate");
688 TaxonDescription taxonDescription
=null;
689 if (taxon
.getTitleCache().contains("Chenopodium vulvaria L.")) {
690 taxonDescription
= (TaxonDescription
) getDescriptionService().find(UUID
.fromString("a60074e7-979b-41fd-ad4d-d391db474ac4"));
692 if(!taxon
.getTitleCache().contains("Chenopodium vulvaria L.") || taxonDescription
==null) {
693 taxonDescription
= getTaxonDescription(taxon
, ref
, false, true);
694 taxonDescription
.setTitleCache(ref
.getTitleCache(), true);
698 taxon
.addDescription(taxonDescription
);
700 IndividualsAssociation indAssociation
= IndividualsAssociation
.NewInstance();
701 Feature feature
= makeFeature(derivedUnitBase
);
702 indAssociation
.setAssociatedSpecimenOrObservation(derivedUnitBase
);
703 indAssociation
.setFeature(feature
);
705 for (Reference
<?
> citation
: determinationEvent
.getReferences()) {
706 indAssociation
.addSource(DescriptionElementSource
.NewInstance(OriginalSourceType
.PrimaryTaxonomicSource
, null, null, citation
, null));
709 taxonDescription
.addElement(indAssociation
);
710 taxonDescription
.setTaxon(taxon
);
712 getDescriptionService().saveOrUpdate(taxonDescription
);
713 getTaxonService().saveOrUpdate(taxon
);
718 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#isIgnore(eu.etaxonomy.cdm.io.common.IoStateBase)
721 protected boolean isIgnore(SpecimenSynthesysExcelImportState state
) {
727 * @see eu.etaxonomy.cdm.io.specimen.SpecimenIoBase#doInvoke(eu.etaxonomy.cdm.io.specimen.abcd206.SpecimenImportState)
730 protected void doInvoke(SpecimenSynthesysExcelImportState state
) {
731 boolean success
= true;
732 if (state
.getConfig().doAskForDate()) {
733 keepAtomisedDate
= askQuestion("Gathering dates can be stored in either atomised fieds (day month year) or in a concatenated field."+
734 "\nWhich value do you want to store?\nPress 1 for the atomised, press 2 for the concatenated field, and then press enter.");
737 tx
= startTransaction();
739 ref
= state
.getConfig().getTaxonReference();
741 ref
= state
.getConfig().getSourceReference();
743 getReferenceService().saveOrUpdate(ref
);
744 setClassification(state
);
746 refreshTransaction();
748 URI source
= state
.getConfig().getSource();
749 ArrayList
<HashMap
<String
,String
>> unitsList
= null;
751 unitsList
= ExcelUtils
.parseXLS(source
);
752 } catch(FileNotFoundException e
){
753 String message
= "File not found: " + source
;
754 warnProgress(state
, message
, e
);
755 logger
.error(message
);
758 logger
.info("unitslist : "+unitsList
.size());
759 if (unitsList
!= null){
760 //load collectors in the database
761 prepareCollectors(unitsList
,state
);
762 HashMap
<String
,String
> unit
=null;
763 MyHashMap
<String
,String
> myunit
;
764 for (int i
=0; i
<unitsList
.size();i
++){
766 logger
.info("NbUnit prepared: "+i
);
767 refreshTransaction();
769 unit
= unitsList
.get(i
);
770 myunit
=new MyHashMap
<String
, String
>();
771 for (String key
:unit
.keySet()) {
772 myunit
.put(key
, unit
.get(key
));
774 //FIXME do this via state
775 setUnitPropertiesExcel(myunit
, state
.getConfig().getDefaultAuthor());//and then invoke
776 success
&= start(state
.getConfig());
779 if (success
== false){
780 state
.setUnsuccessfull();
782 commitTransaction(tx
);
791 private void prepareCollectors(ArrayList
<HashMap
<String
, String
>> unitsList
, SpecimenSynthesysExcelImportState state
) {
792 List
<String
> collectors
= new ArrayList
<String
>();
793 List
<String
> teams
= new ArrayList
<String
>();
794 List
<List
<String
>> collectorinteams
= new ArrayList
<List
<String
>>();
796 for (HashMap
<String
,String
> unit
:unitsList
){
798 tmp
= unit
.get("collector");
799 if (tmp
!= null && !tmp
.isEmpty()) {
800 if (tmp
.indexOf("et al.") != -1 || tmp
.indexOf(" al. ")!=-1 || tmp
.indexOf("& al.")!=-1 ) {
801 if (!tmp
.trim().isEmpty()) {
802 teams
.add(tmp
.trim());
805 if(tmp
.indexOf(" et ")!=-1 || tmp
.indexOf("&")!=-1){
806 List
<String
> collteam
= new ArrayList
<String
>();
807 String
[] tmp1
= tmp
.split(" et ");
808 for (String elt
:tmp1
){
809 String tmp2
[] = elt
.split("&");
810 for (String elt2
:tmp2
) {
811 if (!elt2
.trim().isEmpty()) {
812 collectors
.add(elt2
.trim());
813 collteam
.add(elt2
.trim());
817 if (collteam
.size()>0) {
818 collectorinteams
.add(new ArrayList
<String
>(new HashSet
<String
>(collteam
)));
822 if (!tmp
.trim().isEmpty() && !tmp
.toString().trim().equalsIgnoreCase("none")) {
823 collectors
.add(tmp
.trim());
829 List
<String
> collectorsU
= new ArrayList
<String
>(new HashSet
<String
>(collectors
));
830 List
<String
> teamsU
= new ArrayList
<String
>(new HashSet
<String
>(teams
));
833 //existing teams in DB
834 Map
<String
,Team
> titleCacheTeam
= new HashMap
<String
, Team
>();
835 List
<UuidAndTitleCache
<Team
>> hiberTeam
= getAgentService().getTeamUuidAndTitleCache();
837 Set
<UUID
> uuids
= new HashSet
<UUID
>();
838 for (UuidAndTitleCache
<Team
> hibernateT
:hiberTeam
){
839 uuids
.add(hibernateT
.getUuid());
841 if (!uuids
.isEmpty()){
842 List
<AgentBase
> existingTeams
= getAgentService().find(uuids
);
843 for (AgentBase existingP
:existingTeams
){
844 titleCacheTeam
.put(existingP
.getTitleCache(),(Team
) existingP
);
849 Map
<String
,UUID
> teamMap
= new HashMap
<String
, UUID
>();
850 for (UuidAndTitleCache
<Team
> uuidt
:hiberTeam
){
851 teamMap
.put(uuidt
.getTitleCache(), uuidt
.getUuid());
854 //existing persons in DB
855 List
<UuidAndTitleCache
<Person
>> hiberPersons
= getAgentService().getPersonUuidAndTitleCache();
856 Map
<String
,Person
> titleCachePerson
= new HashMap
<String
, Person
>();
857 uuids
= new HashSet
<UUID
>();
858 for (UuidAndTitleCache
<Person
> hibernateP
:hiberPersons
){
859 uuids
.add(hibernateP
.getUuid());
862 if (!uuids
.isEmpty()){
863 List
<AgentBase
> existingPersons
= getAgentService().find(uuids
);
864 for (AgentBase existingP
:existingPersons
){
865 titleCachePerson
.put(existingP
.getTitleCache(),(Person
) existingP
);
869 Map
<String
,UUID
> personMap
= new HashMap
<String
, UUID
>();
870 for (UuidAndTitleCache
<Person
> person
:hiberPersons
){
871 personMap
.put(person
.getTitleCache(), person
.getUuid());
874 java
.util
.Collection
<AgentBase
> personToadd
= new ArrayList
<AgentBase
>();
875 java
.util
.Collection
<AgentBase
> teamToAdd
= new ArrayList
<AgentBase
>();
877 for (String collector
:collectorsU
){
878 Person p
= Person
.NewInstance();
879 p
.setTitleCache(collector
,true);
880 if (!personMap
.containsKey(p
.getTitleCache())){
884 for (String team
:teamsU
){
885 Team p
= Team
.NewInstance();
886 p
.setTitleCache(team
,true);
887 if (!teamMap
.containsKey(p
.getTitleCache())){
891 Map
<UUID
, AgentBase
> uuuidPerson
= getAgentService().save(personToadd
);
892 for (UUID u
:uuuidPerson
.keySet()){
893 titleCachePerson
.put(uuuidPerson
.get(u
).getTitleCache(),(Person
) uuuidPerson
.get(u
) );
898 Map
<String
,Integer
>teamdone
= new HashMap
<String
, Integer
>();
899 for (List
<String
> collteam
: collectorinteams
){
900 if (!teamdone
.containsKey(StringUtils
.join(collteam
.toArray(),"-"))){
901 Team team
= new Team();
903 for (String collector
:collteam
){
904 ptmp
= Person
.NewInstance();
905 ptmp
.setTitleCache(collector
,true);
906 Person p2
= titleCachePerson
.get(ptmp
.getTitleCache());
907 team
.addTeamMember(p2
);
913 teamdone
.put(StringUtils
.join(collteam
.toArray(),"-"),0);
918 Map
<UUID
, AgentBase
> uuuidTeam
= getAgentService().save(teamToAdd
);
920 for (UUID u
:uuuidTeam
.keySet()){
921 titleCacheTeam
.put(uuuidTeam
.get(u
).getTitleCache(), (Team
) uuuidTeam
.get(u
) );
924 state
.getConfig().setTeams(titleCacheTeam
);
925 state
.getConfig().setPersons(titleCachePerson
);
928 private boolean askQuestion(String question
){
929 Scanner scan
= new Scanner(System
.in
);
930 System
.out
.println(question
);
931 int index
= scan
.nextInt();
943 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doCheck(eu.etaxonomy.cdm.io.common.IoStateBase)
946 protected boolean doCheck(SpecimenSynthesysExcelImportState state
) {
947 logger
.warn("Validation not yet implemented for " + getClass().getSimpleName());