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
.NonViralName
;
53 import eu
.etaxonomy
.cdm
.model
.occurrence
.Collection
;
54 import eu
.etaxonomy
.cdm
.model
.occurrence
.DerivedUnit
;
55 import eu
.etaxonomy
.cdm
.model
.occurrence
.DeterminationEvent
;
56 import eu
.etaxonomy
.cdm
.model
.occurrence
.GatheringEvent
;
57 import eu
.etaxonomy
.cdm
.model
.occurrence
.SpecimenOrObservationBase
;
58 import eu
.etaxonomy
.cdm
.model
.occurrence
.SpecimenOrObservationType
;
59 import eu
.etaxonomy
.cdm
.model
.reference
.Reference
;
60 import eu
.etaxonomy
.cdm
.model
.reference
.ReferenceFactory
;
61 import eu
.etaxonomy
.cdm
.model
.taxon
.Classification
;
62 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
63 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
64 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonNode
;
65 import eu
.etaxonomy
.cdm
.persistence
.dto
.UuidAndTitleCache
;
66 import eu
.etaxonomy
.cdm
.strategy
.parser
.NonViralNameParserImpl
;
67 import eu
.etaxonomy
.cdm
.strategy
.parser
.TimePeriodParser
;
76 public class SpecimenSythesysExcelImport
extends CdmImportBase
<SpecimenSynthesysExcelImportConfigurator
, SpecimenSynthesysExcelImportState
>
77 implements ICdmIO
<SpecimenSynthesysExcelImportState
> {
79 private static final Logger logger
= Logger
.getLogger(SpecimenSythesysExcelImport
.class);
81 protected String fullScientificNameString
;
82 protected String nomenclatureCode
;
83 protected String institutionCode
;
84 protected String collectionCode
;
85 protected String unitID
;
86 protected String recordBasis
;
87 protected String accessionNumber
;
88 protected String fieldNumber
;
89 protected Double longitude
;
90 protected Double latitude
;
91 protected String locality
;
92 protected String languageIso
= null;
93 protected String country
;
94 protected String isocountry
;
96 protected int altitude
;
97 protected String gatheringYear
;
98 protected String gatheringMonth
;
99 protected String gatheringDay
;
100 protected String gatheringDate
;
101 protected String gatheringTeam
;
102 protected String gatheringAgent
;
103 protected String originalsource
;
104 protected String identifier
;
105 protected String gatheringNotes
;
107 private DerivedUnit derivedUnitBase
;
108 private Reference
<?
> ref
= null;
109 private TransactionStatus tx
;
110 private Classification classification
= null;
112 protected ArrayList
<String
> identificationList
= new ArrayList
<String
>();
113 protected ArrayList
<String
> multimediaObjects
= new ArrayList
<String
>();
114 private boolean keepAtomisedDate
=true;
115 private boolean useTDWGarea
= true;
117 boolean DEBUG
=false;
119 public SpecimenSythesysExcelImport() {
124 * private HashMap that handle null values (missing keys)
125 * return empty string instead of null
127 public class MyHashMap
<K
,V
> extends HashMap
<K
,V
> {
131 private static final long serialVersionUID
= -6230407405666753405L;
133 @SuppressWarnings("unchecked")
135 public V
get(Object key
) {
137 if (containsKey(key
)) {
142 if (a
==null || a
.toString().equalsIgnoreCase("none")) {
151 * getClassification : get the classification declared in the ImportState
156 private void setClassification(SpecimenSynthesysExcelImportState state
) {
157 if (classification
== null){
158 boolean configreused
=false;
159 if (state
.getConfig().getClassificationName()!=null && state
.getConfig().getClassificationName().equalsIgnoreCase("Goosefoots")) {
160 classification
= getClassificationService().find(UUID
.fromString("2c2dc41c-9891-42cd-9cd5-8b28dfdd1b8a"));
161 if (classification
==null){
162 String name
= state
.getConfig().getClassificationName();
163 classification
= Classification
.NewInstance(name
, ref
, Language
.DEFAULT());
164 getClassificationService().saveOrUpdate(classification
);
168 if (state
.getConfig().getClassificationName()!=null && state
.getConfig().getClassificationName().equalsIgnoreCase("Ants")) {
169 classification
= getClassificationService().find(UUID
.fromString("9b72d32f-2868-4f0d-81bd-ebc38ee8c645"));
170 if (classification
==null){
171 String name
= state
.getConfig().getClassificationName();
172 classification
= Classification
.NewInstance(name
, ref
, Language
.DEFAULT());
173 getClassificationService().saveOrUpdate(classification
);
177 if (state
.getConfig().getClassificationName()!=null && state
.getConfig().getClassificationName().equalsIgnoreCase("Fungi")) {
178 classification
= getClassificationService().find(UUID
.fromString("fe07274d-daff-4678-9f7d-2c3916948c3e"));
179 if (classification
==null){
180 String name
= state
.getConfig().getClassificationName();
181 classification
= Classification
.NewInstance(name
, ref
, Language
.DEFAULT());
182 getClassificationService().saveOrUpdate(classification
);
186 if (state
.getConfig().getClassificationName()!=null && state
.getConfig().getClassificationName().equalsIgnoreCase("Campylopus")) {
187 classification
= getClassificationService().find(UUID
.fromString("9dccbd11-eb0e-4cac-ae04-aa61ad82b8a6"));
188 if (classification
==null){
189 String name
= state
.getConfig().getClassificationName();
190 classification
= Classification
.NewInstance(name
, ref
, Language
.DEFAULT());
191 getClassificationService().saveOrUpdate(classification
);
196 if (state
.getConfig().getClassificationName()!=null && state
.getConfig().getClassificationName().equalsIgnoreCase("Eupolybothrus")) {
197 classification
= getClassificationService().find(UUID
.fromString("62ce65e0-e036-49aa-aae7-4d4d0f88966c"));
198 if (classification
==null){
199 String name
= state
.getConfig().getClassificationName();
200 classification
= Classification
.NewInstance(name
, ref
, Language
.DEFAULT());
201 getClassificationService().saveOrUpdate(classification
);
207 String name
= state
.getConfig().getClassificationName();
208 classification
= Classification
.NewInstance(name
, ref
, Language
.DEFAULT());
209 if (state
.getConfig().getClassificationUuid() != null) {
210 classification
.setUuid(state
.getConfig().getClassificationUuid());
212 getClassificationService().saveOrUpdate(classification
);
219 * refresh the hibernate transaction :
220 * - commit the current queries
221 * - get the reference and the classification and the derivedUnitBase back from the hibernate session
223 private void refreshTransaction(){
224 commitTransaction(tx
);
225 tx
= startTransaction();
226 ref
= getReferenceService().find(ref
.getUuid());
227 classification
= getClassificationService().find(classification
.getUuid());
229 derivedUnitBase
= (DerivedUnit
) getOccurrenceService().find(derivedUnitBase
.getUuid());
231 //logger.warn("derivedunit up to date or not created yet");
236 // * refresh the hibernate transaction :
237 // * - commit the current queries
238 // * - get the reference and the classification and the derivedUnitBase back from the hibernate session
240 // private void refreshTransac(){
241 // commitTransaction(tx);
242 // tx = startTransaction();
245 * Store the unit's properties into variables
246 * @param unit: the hashmap containing the splitted Excel line (Key=column name, value=value)
248 private void setUnitPropertiesExcel(MyHashMap
<String
,String
> unit
, String defaultAuthor
){
249 multimediaObjects
= new ArrayList
<String
>();
250 identificationList
= new ArrayList
<String
>();
254 String author
= unit
.get("author");
255 if (author
.isEmpty() && !defaultAuthor
.isEmpty()) {
256 author
=defaultAuthor
;
258 String taxonName
= unit
.get("taxonName");
260 institutionCode
= unit
.get("institution");
261 collectionCode
= unit
.get("collection");
262 unitID
= unit
.get("unitID");
263 recordBasis
= unit
.get("recordBasis");
265 accessionNumber
= null;
267 try {longitude
= Double
.valueOf(unit
.get("longitude"));
268 } catch (Exception e
) {longitude
= 0.0;}
270 try {latitude
= Double
.valueOf(unit
.get("latitude"));
271 } catch (Exception e
) {latitude
= 0.0;}
273 country
= unit
.get("country");
274 isocountry
= unit
.get("isoCountry");
275 locality
= unit
.get("locality");
276 String habitat
= unit
.get("habitat");
277 String stateProvince
= unit
.get("stateProvince");
278 if (!stateProvince
.isEmpty()) {
279 locality
=stateProvince
+", "+locality
;
281 if (!habitat
.isEmpty()){
282 locality
+=" (Habitat: "+habitat
+")";
285 fieldNumber
= unit
.get("field number");
287 String url
=unit
.get("url");
288 if (!url
.isEmpty()) {
289 multimediaObjects
.add(url
);
292 String coll
=unit
.get("collector");
293 if (!coll
.isEmpty()) {
294 if (coll
.indexOf("& al.")!=-1 || coll
.indexOf("et al.") != -1 || coll
.indexOf(" al. ")!=-1 ||
295 coll
.indexOf("&") != -1 || coll
.indexOf(" et ") != -1 || coll
.indexOf(";")!=-1) {
296 gatheringTeam
= coll
;
299 gatheringAgent
= coll
;
303 if(!taxonName
.contains(author
)) {
304 identificationList
.add(taxonName
+" "+author
);
306 identificationList
.add(taxonName
);
309 gatheringYear
= unit
.get("year");
310 gatheringMonth
= unit
.get("month");
311 gatheringDay
= unit
.get("day");
312 gatheringDate
= unit
.get("date");
314 gatheringNotes
= unit
.get("eventRemarks");
315 originalsource
= unit
.get("originalsource");
316 identifier
= unit
.get("identifier");
320 private Institution
getInstitution(SpecimenSynthesysExcelImportConfigurator config
){
321 Institution institution
;
322 List
<Institution
> institutions
;
324 institutions
= getAgentService().searchInstitutionByCode(institutionCode
);
326 institutions
=new ArrayList
<Institution
>();
328 if (institutions
.size() ==0 || !config
.getReUseExistingMetadata()){
329 logger
.debug("Institution (agent) unknown or not allowed to reuse existing metadata");
331 institution
= Institution
.NewInstance();
332 institution
.setCode(institutionCode
);
333 getAgentService().saveOrUpdate(institution
);
336 logger
.debug("Institution (agent) already in the db");
337 institution
= institutions
.get(0);
339 return CdmBase
.deproxy(institution
, Institution
.class);
343 * Look if the Collection does already exists
344 * @param collectionCode: a string
345 * @param institution: the current Institution
347 * @return the Collection (existing or new)
349 private Collection
getCollection(Institution institution
, SpecimenSynthesysExcelImportConfigurator config
){
350 Collection collection
=null;
351 List
<Collection
> collections
;
353 collections
= getCollectionService().searchByCode(collectionCode
);
355 collections
=new ArrayList
<Collection
>();
357 if (collections
.size() ==0 || !config
.getReUseExistingMetadata()){
358 logger
.debug("Collection not found or do not reuse existing metadata "+collectionCode
);
359 //create new collection
360 collection
= Collection
.NewInstance();
361 collection
.setCode(collectionCode
);
362 collection
.setCodeStandard("GBIF");
363 collection
.setInstitute(institution
);
366 boolean collectionFound
=false;
367 for (int i
=0; i
<collections
.size(); i
++){
368 collection
= collections
.get(i
);
370 if (collection
.getInstitute().getCode().equalsIgnoreCase(institution
.getCode())){
371 //found a collection with the same code and the same institution
372 collectionFound
=true;
374 } catch (NullPointerException e
) {}
376 if (!collectionFound
){
377 collection
= Collection
.NewInstance();
378 collection
.setCode(collectionCode
);
379 collection
.setCodeStandard("GBIF");
380 collection
.setInstitute(institution
);
390 * @param derivedThing
393 private void setTaxonNameBase(SpecimenSynthesysExcelImportConfigurator config
){
394 NonViralName
<?
> taxonName
= null;
397 String scientificName
="";
398 boolean preferredFlag
=false;
400 for (int i
= 0; i
< identificationList
.size(); i
++) {
401 String fullScientificNameString
= identificationList
.get(i
);
402 fullScientificNameString
= fullScientificNameString
.replaceAll(" et ", " & ");
403 if (fullScientificNameString
.indexOf("_preferred_") != -1){
404 scientificName
= fullScientificNameString
.split("_preferred_")[0].trim();
405 String pTmp
= fullScientificNameString
.split("_preferred_")[1].split("_code_")[0];
406 if (pTmp
== "1" || pTmp
.toLowerCase().indexOf("true") != -1) {
412 scientificName
= fullScientificNameString
.trim();
415 if (fullScientificNameString
.indexOf("_code_") != -1){
416 nomenclatureCode
= fullScientificNameString
.split("_code_")[1].trim();
419 if (config
.getDoReUseTaxon()){
420 List
<TaxonBase
> c
= null;
422 Taxon cc
= getTaxonService().findBestMatchingTaxon(scientificName
);
424 if ((cc
.getSec() == null || cc
.getSec().toString().isEmpty()) || (cc
.getSec() != null &&
425 cc
.getSec().getTitleCache().equalsIgnoreCase(ref
.getTitleCache()))) {
426 if(cc
.getSec() == null || cc
.getSec().toString().isEmpty()){
428 getTaxonService().saveOrUpdate(cc
);
434 c
= getTaxonService().searchTaxaByName(scientificName
, ref
);
435 for (TaxonBase
<?
> b
: c
) {
439 } catch (Exception e
) {
440 logger
.info("Searchtaxabyname failed" + e
);
445 if (!config
.getDoReUseTaxon() || taxon
== null){
447 logger
.info("create new taxonName instance");
449 if (config
.getDoAutomaticParsing()){
450 taxonName
= parseScientificName(scientificName
);
453 taxonName
= NonViralName
.NewInstance(null);
454 taxonName
.setTitleCache(scientificName
, true);
456 getNameService().save(taxonName
);
457 taxon
= Taxon
.NewInstance(taxonName
, ref
); //sec set null
458 getTaxonService().save(taxon
);
459 // refreshTransaction();
460 taxon
= (Taxon
) getTaxonService().find(taxon
.getUuid());
461 taxon
= addTaxonNode(taxon
, config
);
466 DeterminationEvent determinationEvent
= DeterminationEvent
.NewInstance();
467 determinationEvent
.setTaxon(getTaxonService().find(taxon
.getUuid()));
468 determinationEvent
.setPreferredFlag(preferredFlag
);
470 determinationEvent
.setIdentifiedUnit(derivedUnitBase
);
471 if (!identifier
.isEmpty()){
472 Person p
= Person
.NewInstance();
473 p
.setTitleCache(identifier
, true);
474 determinationEvent
.setActor(p
);
476 derivedUnitBase
.addDetermination(determinationEvent
);
478 makeIndividualsAssociation(taxon
,determinationEvent
,config
);
480 getOccurrenceService().saveOrUpdate(derivedUnitBase
);
491 private Taxon
addTaxonNode(Taxon taxon
, SpecimenSynthesysExcelImportConfigurator config
) {
493 logger
.info("link taxon to a taxonNode");
495 boolean exist
= false;
496 for (TaxonNode p
: classification
.getAllNodes()){
497 if(p
.getTaxon().equals(taxon
)) {
502 taxon
= (Taxon
) getTaxonService().find(taxon
.getUuid());
503 classification
.addChildTaxon(taxon
, ref
, null);
504 getClassificationService().saveOrUpdate(classification
);
505 // refreshTransaction();
507 return (Taxon
) getTaxonService().find(taxon
.getUuid());
510 private NonViralName
<?
> parseScientificName(String scientificName
){
512 logger
.debug("in parseScientificName");
514 NonViralNameParserImpl nvnpi
= NonViralNameParserImpl
.NewInstance();
515 NonViralName
<?
>taxonName
= null;
516 boolean problem
=false;
519 logger
.debug("nomenclature: "+nomenclatureCode
);
522 if(nomenclatureCode
== null){
523 taxonName
= NonViralName
.NewInstance(null);
524 taxonName
.setTitleCache(scientificName
, true);
528 if (nomenclatureCode
.toString().equals("Zoological")){
529 taxonName
= nvnpi
.parseFullName(scientificName
,NomenclaturalCode
.ICZN
,null);
530 if (taxonName
.hasProblem()) {
534 if (nomenclatureCode
.toString().equals("Botanical")){
535 taxonName
= nvnpi
.parseFullName(scientificName
,NomenclaturalCode
.ICNAFP
,null);
536 if (taxonName
.hasProblem()) {
539 if (nomenclatureCode
.toString().equals("Bacterial")){
540 taxonName
= nvnpi
.parseFullName(scientificName
,NomenclaturalCode
.ICNB
, null);
541 if (taxonName
.hasProblem()) {
545 if (nomenclatureCode
.toString().equals("Cultivar")){
546 taxonName
= nvnpi
.parseFullName(scientificName
,NomenclaturalCode
.ICNCP
, null);
547 if (taxonName
.hasProblem()) {
551 // if (nomenclatureCode.toString().equals("Viral")){
552 // ViralName taxonName = (ViralName)nvnpi.parseFullName(scientificName,NomenclaturalCode.ICVCN(), null);
553 // if (taxonName.hasProblem())
554 // System.out.println("pb ICVCN");
556 //TODO: parsing of ViralNames?
558 taxonName
= NonViralName
.NewInstance(null);
559 taxonName
.setTitleCache(scientificName
, true);
565 private DerivedUnitFacade
getFacade() {
566 // logger.info("GETFACADE");
568 * SPECIMEN OR OBSERVATION OR LIVING
570 // DerivedUnit derivedThing = null;
571 SpecimenOrObservationType type
= null;
574 if (recordBasis
!= null) {
575 String rec
= recordBasis
.toLowerCase();
576 if (rec
.contains("specimen") || rec
.startsWith("s")) {// specimen
577 type
= SpecimenOrObservationType
.PreservedSpecimen
;
579 if (rec
.contains("observat") || rec
.startsWith("o")) {
580 type
= SpecimenOrObservationType
.Observation
;
582 if (rec
.contains("fossil") || rec
.startsWith("f") ){
583 type
= SpecimenOrObservationType
.Fossil
;
586 if (rec
.contains("living") || rec
.startsWith("l")) {
587 type
= SpecimenOrObservationType
.LivingSpecimen
;
591 logger
.info("The basis of record does not seem to be known: " + recordBasis
);
593 type
= SpecimenOrObservationType
.DerivedUnit
;
596 logger
.info("The basis of record is null");
597 type
= SpecimenOrObservationType
.DerivedUnit
;
599 DerivedUnitFacade derivedUnitFacade
= DerivedUnitFacade
.NewInstance(type
);
600 return derivedUnitFacade
;
604 * Store the unit with it's Gathering informations in the CDM
606 public boolean start(SpecimenSynthesysExcelImportConfigurator config
){
607 boolean result
= true;
609 // refreshTransaction();
613 * SPECIMEN OR OBSERVATION OR LIVING
615 DerivedUnitFacade derivedUnitFacade
= getFacade();
616 derivedUnitBase
= derivedUnitFacade
.innerDerivedUnit();
618 //set catalogue number (unitID)
619 derivedUnitFacade
.setCatalogNumber(unitID
);
620 derivedUnitFacade
.setAccessionNumber(accessionNumber
);
622 if (!originalsource
.isEmpty()){
623 Reference
<?
> reference
= ReferenceFactory
.newGeneric();
624 reference
.setTitleCache(originalsource
, true);
625 derivedUnitBase
.addSource(OriginalSourceType
.Import
, originalsource
, "", reference
, "");
627 derivedUnitBase
.addSource(OriginalSourceType
.Import
, unitID
,"",ref
,ref
.getCitation());
630 * INSTITUTION & COLLECTION
633 if (!institutionCode
.isEmpty()){
634 Institution institution
= getInstitution(config
);
636 if (!collectionCode
.isEmpty()){
637 Collection collection
= getCollection(institution
, config
);
638 //link specimen & collection
639 derivedUnitFacade
.setCollection(collection
);
647 UnitsGatheringEvent unitsGatheringEvent
= new UnitsGatheringEvent(getTermService(), locality
, languageIso
,
648 longitude
, latitude
, gatheringAgent
, gatheringTeam
,config
);
650 UnitsGatheringArea unitsGatheringArea
= new UnitsGatheringArea();
651 unitsGatheringArea
.useTDWGareas(this.useTDWGarea
);
652 // unitsGatheringArea.setConfig(config, getOccurrenceService(),getTermService());
653 unitsGatheringArea
.setParams(isocountry
, country
, config
, getTermService(), getOccurrenceService());
654 DefinedTermBase areaCountry
=unitsGatheringArea
.getCountry();
658 // copy gathering event to facade
659 GatheringEvent gatheringEvent
= unitsGatheringEvent
.getGatheringEvent();
660 //join gatheringEvent to fieldObservation
661 derivedUnitFacade
.setGatheringEvent(gatheringEvent
);
663 derivedUnitFacade
.setLocality(gatheringEvent
.getLocality());
664 derivedUnitFacade
.setExactLocation(gatheringEvent
.getExactLocation());
665 //derivedUnitFacade.setCollector(gatheringEvent.getCollector());
666 derivedUnitFacade
.setCountry((NamedArea
)areaCountry
);
667 for(DefinedTermBase
<?
> area
:unitsGatheringArea
.getAreas()){
668 derivedUnitFacade
.addCollectingArea((NamedArea
) area
);
670 if (gatheringNotes
!= null && !gatheringNotes
.isEmpty()) {
671 derivedUnitFacade
.setFieldNotes(gatheringNotes
);
676 * merge AND STORE DATA
678 // getTermService().saveOrUpdate(areaCountry);// TODO save area sooner
679 getTermService().saveLanguageData(unitsGatheringEvent
.getLocality());
684 if (keepAtomisedDate
&& (!gatheringYear
.isEmpty() || !gatheringMonth
.isEmpty() || !gatheringDay
.isEmpty())){
685 Calendar calendar
= Calendar
.getInstance();
686 if (!gatheringYear
.isEmpty()) {
687 TimePeriod tp
= TimePeriod
.NewInstance(Integer
.parseInt(gatheringYear
));
688 if (!gatheringMonth
.isEmpty()) {
689 tp
.setStartMonth(Integer
.parseInt(gatheringMonth
));
690 if (!gatheringDay
.isEmpty()) {
691 tp
.setStartDay(Integer
.parseInt(gatheringDay
));
694 unitsGatheringEvent
.setGatheringDate(tp
);
698 if (!gatheringDate
.isEmpty()){
699 TimePeriod tp
= TimePeriodParser
.parseString(gatheringDate
);
700 unitsGatheringEvent
.setGatheringDate(tp
);
706 derivedUnitFacade
.setFieldNumber(fieldNumber
);
708 //add Multimedia URLs
709 if(multimediaObjects
.size()>0){
710 for (String multimediaObject
: multimediaObjects
) {
713 media
= getImageMedia(multimediaObject
, READ_MEDIA_DATA
);
714 derivedUnitFacade
.addDerivedUnitMedia(media
);
715 } catch (MalformedURLException e
) {
716 // TODO Auto-generated catch block
722 getOccurrenceService().saveOrUpdate(derivedUnitBase
);
724 setTaxonNameBase(config
);
726 // refreshTransaction();
728 logger
.info("saved new specimen ...");
731 } catch (Exception e
) {
732 logger
.warn("Error when reading record!!");
737 logger
.info("commit done");
744 * Store the unit with it's Gathering informations in the CDM
746 public boolean resetCollectionInstitution(SpecimenSynthesysExcelImportConfigurator config
,List
<SpecimenOrObservationBase
> specimenOrObs
){
747 boolean result
= true;
750 for (SpecimenOrObservationBase
<?
> specimen
:specimenOrObs
){
751 DerivedUnit derivedUnit
=null;
752 if (specimen
.isInstanceOf(GatheringEvent
.class)){
753 System
.out
.println("gathering");
754 GatheringEvent gath
= CdmBase
.deproxy(specimen
, GatheringEvent
.class);
756 if (specimen
.isInstanceOf(DerivedUnit
.class)){
757 derivedUnit
= CdmBase
.deproxy(specimen
, DerivedUnit
.class);
758 String unitIDDB
= derivedUnit
.getCatalogNumber();
759 if (unitIDDB
!=null) {
760 if(unitIDDB
.equalsIgnoreCase(this.unitID
)){
761 System
.out
.println("unitID found");
763 Institution institution
= getInstitution(config
);
765 Collection col
= getCollection(institution
, config
);
766 getCollectionService().saveOrUpdate(col
);
767 derivedUnit
.setCollection(col
);
768 getOccurrenceService().saveOrUpdate(derivedUnit
);
773 if(specimen
.isInstanceOf(IndividualsAssociation
.class)) {
774 System
.out
.println("Indivi assoc");
781 private Feature
makeFeature(SpecimenOrObservationBase
<?
> unit
) {
785 SpecimenOrObservationType type
= unit
.getRecordBasis();
787 if (type
.isFeatureObservation()){
788 return Feature
.OBSERVATION();
789 }else if (type
.isPreservedSpecimen() ||
790 type
== SpecimenOrObservationType
.LivingSpecimen
||
791 type
== SpecimenOrObservationType
.OtherSpecimen
793 return Feature
.SPECIMEN();
794 }else if (type
== SpecimenOrObservationType
.Unknown
||
795 type
== SpecimenOrObservationType
.DerivedUnit
797 return Feature
.INDIVIDUALS_ASSOCIATION();
800 logger
.warn("No feature defined for derived unit class: "
801 + unit
.getClass().getSimpleName());
806 private void makeIndividualsAssociation(Taxon taxon
, DeterminationEvent determinationEvent
, SpecimenSynthesysExcelImportConfigurator config
) {
808 // taxon = (Taxon) getTaxonService().find(taxon.getUuid());
810 // catch(Exception e){
811 // //logger.info("taxon uptodate");
814 TaxonDescription taxonDescription
=null;
815 if (taxon
.getTitleCache().contains("Chenopodium vulvaria L.")) {
816 taxonDescription
= (TaxonDescription
) getDescriptionService().find(UUID
.fromString("a60074e7-979b-41fd-ad4d-d391db474ac4"));
818 if(!taxon
.getTitleCache().contains("Chenopodium vulvaria L.") || taxonDescription
==null) {
819 taxonDescription
= getTaxonDescription(taxon
, ref
, false, true);
820 taxonDescription
.setTitleCache(ref
.getTitleCache(), true);
824 taxon
.addDescription(taxonDescription
);
826 IndividualsAssociation indAssociation
= IndividualsAssociation
.NewInstance();
827 Feature feature
= makeFeature(derivedUnitBase
);
828 indAssociation
.setAssociatedSpecimenOrObservation(derivedUnitBase
);
829 indAssociation
.setFeature(feature
);
831 for (Reference
<?
> citation
: determinationEvent
.getReferences()) {
832 indAssociation
.addSource(DescriptionElementSource
.NewInstance(OriginalSourceType
.Import
, null, null, citation
, null));
834 indAssociation
.addSource(OriginalSourceType
.Import
, null,null,config
.getDataReference(),null);
836 taxonDescription
.addElement(indAssociation
);
838 getDescriptionService().saveOrUpdate(taxonDescription
);
839 getTaxonService().saveOrUpdate(taxon
);
843 protected boolean isIgnore(SpecimenSynthesysExcelImportState state
) {
848 protected void doInvoke(SpecimenSynthesysExcelImportState state
) {
849 boolean success
= true;
850 if (state
.getConfig().doAskForDate()) {
851 keepAtomisedDate
= askQuestion("Gathering dates can be stored in either atomised fieds (day month year) or in a concatenated field."+
852 "\nWhich value do you want to store?\nPress 1 for the atomised, press 2 for the concatenated field, and then press enter.");
853 useTDWGarea
= askQuestion("Use TDWG area or Country/namedarea?\n Press 1 for TDWG areas\n Press 2 for classics Country.");
856 tx
= startTransaction();
858 ref
= state
.getConfig().getTaxonReference();
860 ref
= state
.getConfig().getSourceReference();
862 AgentBase
<?
> agent
= ref
.getAuthorship();
864 if (agent
.getClass().equals(Team
.class)){
865 for (Person p
: ((Team
) agent
).getTeamMembers()){
866 getAgentService().saveOrUpdate(p
);
869 if (agent
.getClass().equals(Person
.class)){
870 getAgentService().saveOrUpdate(agent
);
873 getReferenceService().saveOrUpdate(ref
);
874 setClassification(state
);
876 refreshTransaction();
878 URI source
= state
.getConfig().getSource();
879 ArrayList
<HashMap
<String
,String
>> unitsList
= null;
881 unitsList
= ExcelUtils
.parseXLS(source
);
882 logger
.info("unitslist : "+unitsList
.size());
883 } catch(FileNotFoundException e
){
884 String message
= "File not found: " + source
;
885 warnProgress(state
, message
, e
);
886 logger
.error(message
);
889 if (unitsList
!= null){
890 //load collectors in the database
891 if (!state
.getConfig().isDebugInstitutionOnly()) {
892 prepareCollectors(unitsList
,state
);
895 List
<SpecimenOrObservationBase
> specimenOrObs
= null;
896 if (state
.getConfig().isDebugInstitutionOnly()){
897 //DEBUG CHENOPODIUM VULVARIA
898 UUID uuid
= UUID
.fromString("85234ff5-8e40-4813-8f06-44ab960a905a");
899 Taxon taxon
= (Taxon
)getTaxonService().find(uuid
);
901 specimenOrObs
= getOccurrenceService().listByAssociatedTaxon(null, null, taxon
, null, null, null, null, null);
903 HashMap
<String
,String
> unit
=null;
904 MyHashMap
<String
,String
> myunit
;
905 for (int i
=0; i
<unitsList
.size();i
++){
906 // for (int i=0; i<10;i++){
908 logger
.info("NbUnit prepared: "+i
);
909 refreshTransaction();
911 unit
= unitsList
.get(i
);
912 myunit
=new MyHashMap
<String
, String
>();
913 for (String key
:unit
.keySet()) {
914 myunit
.put(key
, unit
.get(key
));
916 System
.out
.println(myunit
.toString());
917 //FIXME do this via state
918 setUnitPropertiesExcel(myunit
, state
.getConfig().getDefaultAuthor());//and then invoke
919 if (state
.getConfig().isDebugInstitutionOnly()){
920 success
&= resetCollectionInstitution(state
.getConfig(),specimenOrObs
);
922 success
&= start(state
.getConfig());
926 if (success
== false){
927 state
.setUnsuccessfull();
929 commitTransaction(tx
);
938 private void prepareCollectors(ArrayList
<HashMap
<String
, String
>> unitsList
, SpecimenSynthesysExcelImportState state
) {
939 System
.out
.println("PREPARE COLLECTORS");
940 List
<String
> collectors
= new ArrayList
<String
>();
941 List
<String
> teams
= new ArrayList
<String
>();
942 List
<List
<String
>> collectorinteams
= new ArrayList
<List
<String
>>();
944 for (HashMap
<String
,String
> unit
: unitsList
){
946 tmp
= unit
.get("collector");
947 if (tmp
!= null && !tmp
.isEmpty()) {
948 if (tmp
.indexOf("et al.") != -1 || tmp
.indexOf(" al. ")!=-1 || tmp
.indexOf("& al.")!=-1 ) {
949 if (!tmp
.trim().isEmpty()) {
950 teams
.add(tmp
.trim());
953 if(tmp
.indexOf(" et ")!=-1 || tmp
.indexOf("&")!=-1 || tmp
.indexOf(";") !=-1){
954 List
<String
> collteam
= new ArrayList
<String
>();
955 String
[] tmp1
= tmp
.split(" et ");
956 for (String elt
:tmp1
){
957 String tmp2
[] = elt
.split("&");
958 for (String elt2
:tmp2
) {
959 if (!elt2
.trim().isEmpty()) {
960 String tmp3
[] = elt
.split(";");
961 for (String elt3
:tmp3
) {
962 if (!elt3
.isEmpty()){
963 collectors
.add(elt3
.trim());
964 collteam
.add(elt3
.trim());
970 if (collteam
.size()>0) {
971 collectorinteams
.add(new ArrayList
<String
>(new HashSet
<String
>(collteam
)));
975 if (!tmp
.trim().isEmpty() && !tmp
.toString().trim().equalsIgnoreCase("none")) {
976 collectors
.add(tmp
.trim());
982 List
<String
> collectorsU
= new ArrayList
<String
>(new HashSet
<String
>(collectors
));
983 List
<String
> teamsU
= new ArrayList
<String
>(new HashSet
<String
>(teams
));
986 //existing teams in DB
987 Map
<String
,Team
> titleCacheTeam
= new HashMap
<String
, Team
>();
988 List
<UuidAndTitleCache
<Team
>> hiberTeam
= getAgentService().getTeamUuidAndTitleCache();
990 Set
<UUID
> uuids
= new HashSet
<UUID
>();
991 for (UuidAndTitleCache
<Team
> hibernateT
:hiberTeam
){
992 uuids
.add(hibernateT
.getUuid());
994 if (!uuids
.isEmpty()){
995 List
<AgentBase
> existingTeams
= getAgentService().find(uuids
);
996 for (AgentBase
<?
> existingP
:existingTeams
){
997 titleCacheTeam
.put(existingP
.getTitleCache(),(Team
) existingP
);
1002 Map
<String
,UUID
> teamMap
= new HashMap
<String
, UUID
>();
1003 for (UuidAndTitleCache
<Team
> uuidt
:hiberTeam
){
1004 teamMap
.put(uuidt
.getTitleCache(), uuidt
.getUuid());
1007 //existing persons in DB
1008 List
<UuidAndTitleCache
<Person
>> hiberPersons
= getAgentService().getPersonUuidAndTitleCache();
1009 Map
<String
,Person
> titleCachePerson
= new HashMap
<String
, Person
>();
1010 uuids
= new HashSet
<UUID
>();
1011 for (UuidAndTitleCache
<Person
> hibernateP
:hiberPersons
){
1012 uuids
.add(hibernateP
.getUuid());
1015 if (!uuids
.isEmpty()){
1016 List
<AgentBase
> existingPersons
= getAgentService().find(uuids
);
1017 for (AgentBase
<?
> existingP
:existingPersons
){
1018 titleCachePerson
.put(existingP
.getTitleCache(),CdmBase
.deproxy(existingP
, Person
.class));
1022 Map
<String
,UUID
> personMap
= new HashMap
<String
, UUID
>();
1023 for (UuidAndTitleCache
<Person
> person
:hiberPersons
){
1024 personMap
.put(person
.getTitleCache(), person
.getUuid());
1027 java
.util
.Collection
<AgentBase
> personsToAdd
= new ArrayList
<AgentBase
>();
1028 java
.util
.Collection
<AgentBase
> teamsToAdd
= new ArrayList
<AgentBase
>();
1030 for (String collector
:collectorsU
){
1031 Person p
= Person
.NewInstance();
1032 p
.setTitleCache(collector
,true);
1033 if (!personMap
.containsKey(p
.getTitleCache())){
1034 personsToAdd
.add(p
);
1037 for (String team
:teamsU
){
1038 Team p
= Team
.NewInstance();
1039 p
.setTitleCache(team
,true);
1040 if (!teamMap
.containsKey(p
.getTitleCache())){
1044 Map
<UUID
, AgentBase
> uuuidPerson
= getAgentService().save(personsToAdd
);
1045 for (UUID u
:uuuidPerson
.keySet()){
1046 titleCachePerson
.put(uuuidPerson
.get(u
).getTitleCache(),CdmBase
.deproxy(uuuidPerson
.get(u
), Person
.class) );
1051 Map
<String
,Integer
>teamdone
= new HashMap
<String
, Integer
>();
1052 for (List
<String
> collteam
: collectorinteams
){
1053 if (!teamdone
.containsKey(StringUtils
.join(collteam
.toArray(),"-"))){
1054 Team team
= new Team();
1056 for (String collector
:collteam
){
1057 ptmp
= Person
.NewInstance();
1058 ptmp
.setTitleCache(collector
,true);
1059 Person p2
= titleCachePerson
.get(ptmp
.getTitleCache());
1060 team
.addTeamMember(p2
);
1064 teamsToAdd
.add(team
);
1066 teamdone
.put(StringUtils
.join(collteam
.toArray(),"-"),0);
1071 Map
<UUID
, AgentBase
> uuuidTeam
= getAgentService().save(teamsToAdd
);
1073 for (UUID u
:uuuidTeam
.keySet()){
1074 titleCacheTeam
.put(uuuidTeam
.get(u
).getTitleCache(), (Team
) uuuidTeam
.get(u
) );
1077 state
.getConfig().setTeams(titleCacheTeam
);
1078 state
.getConfig().setPersons(titleCachePerson
);
1081 private boolean askQuestion(String question
){
1082 Scanner scan
= new Scanner(System
.in
);
1083 System
.out
.println(question
);
1084 int index
= scan
.nextInt();
1094 protected boolean doCheck(SpecimenSynthesysExcelImportState state
) {
1095 logger
.warn("Validation not yet implemented for " + getClass().getSimpleName());