2 * Copyright (C) 2017 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
9 package eu
.etaxonomy
.cdm
.io
.cdmLight
;
12 import java
.util
.ArrayList
;
13 import java
.util
.Collections
;
14 import java
.util
.HashSet
;
15 import java
.util
.Iterator
;
16 import java
.util
.List
;
19 import java
.util
.UUID
;
21 import org
.apache
.commons
.lang3
.StringUtils
;
22 import org
.springframework
.stereotype
.Component
;
24 import eu
.etaxonomy
.cdm
.common
.CdmUtils
;
25 import eu
.etaxonomy
.cdm
.hibernate
.HibernateProxyHelper
;
26 import eu
.etaxonomy
.cdm
.io
.common
.CdmExportBase
;
27 import eu
.etaxonomy
.cdm
.io
.common
.ExportResult
.ExportResultState
;
28 import eu
.etaxonomy
.cdm
.io
.common
.ICdmExport
;
29 import eu
.etaxonomy
.cdm
.io
.common
.mapping
.out
.IExportTransformer
;
30 import eu
.etaxonomy
.cdm
.model
.agent
.AgentBase
;
31 import eu
.etaxonomy
.cdm
.model
.agent
.Person
;
32 import eu
.etaxonomy
.cdm
.model
.agent
.Team
;
33 import eu
.etaxonomy
.cdm
.model
.agent
.TeamOrPersonBase
;
34 import eu
.etaxonomy
.cdm
.model
.common
.Annotation
;
35 import eu
.etaxonomy
.cdm
.model
.common
.AnnotationType
;
36 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
37 import eu
.etaxonomy
.cdm
.model
.common
.DefinedTerm
;
38 import eu
.etaxonomy
.cdm
.model
.common
.ICdmBase
;
39 import eu
.etaxonomy
.cdm
.model
.common
.IIdentifiableEntity
;
40 import eu
.etaxonomy
.cdm
.model
.common
.Language
;
41 import eu
.etaxonomy
.cdm
.model
.common
.LanguageString
;
42 import eu
.etaxonomy
.cdm
.model
.description
.CommonTaxonName
;
43 import eu
.etaxonomy
.cdm
.model
.description
.DescriptionBase
;
44 import eu
.etaxonomy
.cdm
.model
.description
.DescriptionElementBase
;
45 import eu
.etaxonomy
.cdm
.model
.description
.DescriptionElementSource
;
46 import eu
.etaxonomy
.cdm
.model
.description
.Distribution
;
47 import eu
.etaxonomy
.cdm
.model
.description
.Feature
;
48 import eu
.etaxonomy
.cdm
.model
.description
.IndividualsAssociation
;
49 import eu
.etaxonomy
.cdm
.model
.description
.SpecimenDescription
;
50 import eu
.etaxonomy
.cdm
.model
.description
.TaxonDescription
;
51 import eu
.etaxonomy
.cdm
.model
.description
.TaxonNameDescription
;
52 import eu
.etaxonomy
.cdm
.model
.description
.TextData
;
53 import eu
.etaxonomy
.cdm
.model
.location
.NamedArea
;
54 import eu
.etaxonomy
.cdm
.model
.media
.Media
;
55 import eu
.etaxonomy
.cdm
.model
.media
.MediaRepresentation
;
56 import eu
.etaxonomy
.cdm
.model
.media
.MediaRepresentationPart
;
57 import eu
.etaxonomy
.cdm
.model
.name
.HomotypicalGroup
;
58 import eu
.etaxonomy
.cdm
.model
.name
.HomotypicalGroupNameComparator
;
59 import eu
.etaxonomy
.cdm
.model
.name
.NameTypeDesignation
;
60 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalStatus
;
61 import eu
.etaxonomy
.cdm
.model
.name
.Rank
;
62 import eu
.etaxonomy
.cdm
.model
.name
.SpecimenTypeDesignation
;
63 import eu
.etaxonomy
.cdm
.model
.name
.TaxonName
;
64 import eu
.etaxonomy
.cdm
.model
.name
.TypeComparator
;
65 import eu
.etaxonomy
.cdm
.model
.name
.TypeDesignationBase
;
66 import eu
.etaxonomy
.cdm
.model
.occurrence
.DerivedUnit
;
67 import eu
.etaxonomy
.cdm
.model
.occurrence
.FieldUnit
;
68 import eu
.etaxonomy
.cdm
.model
.occurrence
.GatheringEvent
;
69 import eu
.etaxonomy
.cdm
.model
.occurrence
.MediaSpecimen
;
70 import eu
.etaxonomy
.cdm
.model
.occurrence
.SpecimenOrObservationBase
;
71 import eu
.etaxonomy
.cdm
.model
.reference
.Reference
;
72 import eu
.etaxonomy
.cdm
.model
.reference
.ReferenceType
;
73 import eu
.etaxonomy
.cdm
.model
.taxon
.Classification
;
74 import eu
.etaxonomy
.cdm
.model
.taxon
.Synonym
;
75 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
76 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonNode
;
77 import eu
.etaxonomy
.cdm
.strategy
.exceptions
.UnknownCdmTypeException
;
84 public class CdmLightClassificationExport
85 extends CdmExportBase
<CdmLightExportConfigurator
, CdmLightExportState
, IExportTransformer
, File
>
86 implements ICdmExport
<CdmLightExportConfigurator
, CdmLightExportState
>{
89 private static final long serialVersionUID
= 2518643632756927053L;
90 private static final String STD_TEAM_CONCATINATION
= ", ";
91 private static final String FINAL_TEAM_CONCATINATION
= " & ";
93 private static final String IPNI_NAME_IDENTIFIER
= "Ipni Name Identifier";
94 private static final String TROPICOS_NAME_IDENTIFIER
= "Tropicos Name Identifier";
95 private static final String WFO_NAME_IDENTIFIER
= "WFO Name Identifier";
97 public CdmLightClassificationExport() {
99 this.ioName
= this.getClass().getSimpleName();
107 protected void doInvoke(CdmLightExportState state
) {
109 CdmLightExportConfigurator config
= state
.getConfig();
110 config
.setFieldsTerminatedBy(",");
112 if (config
.getClassificationUuids().isEmpty()){
114 state
.setEmptyData();
118 for (UUID classificationUuid
: config
.getClassificationUuids()){
119 handleSingleClassification(state
, classificationUuid
);
121 state
.getProcessor().createFinalResult(state
);
122 } catch (Exception e
) {
123 state
.getResult().addException(e
, "An unexpected error occurred in main method doInvoke() " +
130 * @param classificationUuid
132 private void handleSingleClassification(CdmLightExportState state
, UUID classificationUuid
) {
134 Classification classification
= getClassificationService().find(classificationUuid
);
136 if (classification
== null){
137 String message
= String
.format("Classification for given classification UUID not found. No data imported for %s", classificationUuid
.toString());
139 state
.getResult().addWarning(message
);
141 TaxonNode root
= classification
.getRootNode();
143 UUID uuid
= root
.getUuid();
145 root
= getTaxonNodeService().load(uuid
);
146 for (TaxonNode child
: root
.getChildNodes()){
147 handleTaxon(state
, child
);
148 //TODO progress monitor
151 } catch (Exception e
) {
152 state
.getResult().addException(e
, "An unexpected error occurred when handling classification " +
153 classificationUuid
+ ": " + e
.getMessage());
161 private void handleTaxon(CdmLightExportState state
, TaxonNode taxonNode
) {
163 Taxon taxon
= taxonNode
.getTaxon();
165 state
.getResult().addError ("There was a taxon node without a taxon: " + taxonNode
.getUuid(), "handleTaxon");
166 state
.getResult().setState(ExportResultState
.INCOMPLETE_WITH_ERROR
);
169 TaxonName name
= taxon
.getName();
170 handleName(state
, name
);
171 for (Synonym syn
: taxon
.getSynonyms()){
172 handleSynonym(state
, syn
);
176 CdmLightExportTable table
= CdmLightExportTable
.TAXON
;
177 String
[] csvLine
= new String
[table
.getSize()];
179 csvLine
[table
.getIndex(CdmLightExportTable
.TAXON_ID
)] = getId(state
, taxon
);
180 csvLine
[table
.getIndex(CdmLightExportTable
.NAME_FK
)] = getId(state
, name
);
181 Taxon parent
= (taxonNode
.getParent()==null) ?
null : taxonNode
.getParent().getTaxon();
182 csvLine
[table
.getIndex(CdmLightExportTable
.PARENT_FK
)] = getId(state
, parent
);
183 csvLine
[table
.getIndex(CdmLightExportTable
.SEC_REFERENCE_FK
)] = getId(state
, taxon
.getSec());
184 csvLine
[table
.getIndex(CdmLightExportTable
.SEC_REFERENCE
)] = getTitleCache(taxon
.getSec());
185 csvLine
[table
.getIndex(CdmLightExportTable
.CLASSIFICATION_ID
)] = getId(state
, taxonNode
.getClassification());
186 csvLine
[table
.getIndex(CdmLightExportTable
.CLASSIFICATION_TITLE
)] = taxonNode
.getClassification().getTitleCache();
188 state
.getProcessor().put(table
, taxon
, csvLine
);
189 handleDescriptions(state
, taxon
);
191 state
.getResult().addException (e
, "An unexpected problem occurred when trying to export "
192 + "taxon with id " + taxon
.getId());
193 state
.getResult().setState(ExportResultState
.INCOMPLETE_WITH_ERROR
);
196 for (TaxonNode child
: taxonNode
.getChildNodes()){
197 handleTaxon(state
, child
);
206 private void handleDescriptions(CdmLightExportState state
, CdmBase cdmBase
) {
207 if (cdmBase
instanceof Taxon
){
208 Taxon taxon
= HibernateProxyHelper
.deproxy(cdmBase
, Taxon
.class);
209 Set
<TaxonDescription
> descriptions
= taxon
.getDescriptions();
210 List
<DescriptionElementBase
> simpleFacts
= new ArrayList
<>();
211 List
<DescriptionElementBase
> specimenFacts
= new ArrayList
<>();
212 List
<DescriptionElementBase
> distributionFacts
= new ArrayList
<>();
213 List
<DescriptionElementBase
> commonNameFacts
= new ArrayList
<>();
214 List
<DescriptionElementBase
> usageFacts
= new ArrayList
<>();
215 for (TaxonDescription description
: descriptions
){
216 if (description
.getElements() != null){
217 for (DescriptionElementBase element
: description
.getElements()){
218 element
= CdmBase
.deproxy(element
);
219 if (element
.getFeature().equals(Feature
.COMMON_NAME())){
220 commonNameFacts
.add(element
);
221 }else if (element
.getFeature().equals(Feature
.DISTRIBUTION())){
222 distributionFacts
.add(element
);
223 }else if (element
instanceof IndividualsAssociation
|| isSpecimenFeature(element
.getFeature())){
224 specimenFacts
.add(element
);
226 simpleFacts
.add(element
);
231 if (!commonNameFacts
.isEmpty()){
232 handleCommonNameFacts(state
, taxon
, commonNameFacts
);
234 if (!distributionFacts
.isEmpty()){
235 handleDistributionFacts(state
, taxon
, distributionFacts
);
237 if (!specimenFacts
.isEmpty()){
238 handleSpecimenFacts(state
, taxon
, specimenFacts
);
240 if (!simpleFacts
.isEmpty()){
241 handleSimpleFacts(state
, taxon
, simpleFacts
);
243 } else if (cdmBase
instanceof TaxonName
){
244 TaxonName name
= CdmBase
.deproxy(cdmBase
, TaxonName
.class);
245 Set
<TaxonNameDescription
> descriptions
= name
.getDescriptions();
246 List
<DescriptionElementBase
> simpleFacts
= new ArrayList
<>();
247 for (TaxonNameDescription description
: descriptions
){
248 if (description
.getElements() != null){
249 for (DescriptionElementBase element
: description
.getElements()){
250 if (!element
.getFeature().equals(Feature
.PROTOLOGUE())){
251 simpleFacts
.add(element
);
256 if (!simpleFacts
.isEmpty()){
257 handleSimpleFacts(state
, name
, simpleFacts
);
267 private boolean isSpecimenFeature(Feature feature
) {
268 //TODO allow user defined specimen features
269 if (feature
== null){
271 }else if (feature
.isSupportsIndividualAssociation()){
274 return feature
.equals(Feature
.SPECIMEN()) || feature
.equals(Feature
.INDIVIDUALS_ASSOCIATION())
275 || feature
.equals(Feature
.MATERIALS_EXAMINED()) || feature
.equals(Feature
.OBSERVATION())
276 || feature
.equals(Feature
.OCCURRENCE())
286 private void handleSimpleFacts(CdmLightExportState state
, CdmBase cdmBase
,
287 List
<DescriptionElementBase
> simpleFacts
) {
289 CdmLightExportTable table
= CdmLightExportTable
.SIMPLE_FACT
;
291 for (DescriptionElementBase element
: simpleFacts
){
292 handleSingleSimpleFact(state
, cdmBase
, table
, element
);
294 } catch (Exception e
) {
295 state
.getResult().addException(e
, "An unexpected error occurred when handling simple facts for " +
296 cdmBaseStr(cdmBase
) + ": " + e
.getMessage());
306 private void handleSingleSimpleFact(CdmLightExportState state
, CdmBase cdmBase
, CdmLightExportTable table
,
307 DescriptionElementBase element
) {
310 handleSource(state
, element
, CdmLightExportTable
.SIMPLE_FACT
);
312 if (element
instanceof TextData
){
313 TextData textData
= (TextData
)element
;
314 csvLine
= new String
[table
.getSize()];
315 csvLine
[table
.getIndex(CdmLightExportTable
.FACT_ID
)] = getId(state
, element
);
316 if (cdmBase
instanceof Taxon
){
317 csvLine
[table
.getIndex(CdmLightExportTable
.TAXON_FK
)] = getId(state
, cdmBase
);
318 csvLine
[table
.getIndex(CdmLightExportTable
.NAME_FK
)] = "";
319 }else if (cdmBase
instanceof TaxonName
){
320 csvLine
[table
.getIndex(CdmLightExportTable
.TAXON_FK
)] = "";
321 csvLine
[table
.getIndex(CdmLightExportTable
.NAME_FK
)] = getId(state
, cdmBase
);
323 csvLine
[table
.getIndex(CdmLightExportTable
.FACT_CATEGORY
)] = textData
.getFeature().getLabel();
325 String mediaUris
= "";
326 for (Media media
: textData
.getMedia()){
327 String mediaString
= extractMediaUris(media
.getRepresentations().iterator());
328 if (!StringUtils
.isBlank(mediaString
)){
329 mediaUris
+= mediaString
+ ";";
332 state
.getResult().addWarning("Empty Media object for uuid: " +
333 cdmBase
.getUuid() + " uuid of media: " + media
.getUuid());
336 csvLine
[table
.getIndex(CdmLightExportTable
.MEDIA_URI
)] = mediaUris
;
337 if (textData
.getFeature().equals(Feature
.CITATION())){
338 // csvLine[table.getIndex(CdmLightExportTable.TAXON_FK)] = getId(state, cdmBase);
339 state
.getProcessor().put(table
, textData
, csvLine
);
340 }else if (!textData
.getMultilanguageText().isEmpty()){
341 for (Language language
: textData
.getMultilanguageText().keySet()){
342 String
[] csvLineLanguage
= csvLine
.clone();
343 LanguageString langString
= textData
.getLanguageText(language
);
345 csvLineLanguage
[table
.getIndex(CdmLightExportTable
.FACT_TEXT
)] = langString
.getText();
346 csvLineLanguage
[table
.getIndex(CdmLightExportTable
.LANGUAGE
)] = language
.getLabel();
347 state
.getProcessor().put(table
, textData
, csvLineLanguage
);
350 state
.getProcessor().put(table
, textData
, csvLine
);
353 } catch (Exception e
) {
354 state
.getResult().addException(e
, "An unexpected error occurred when handling single simple fact " +
355 cdmBaseStr(element
) + ": " + e
.getMessage());
362 * @param specimenFacts
364 private void handleSpecimenFacts(CdmLightExportState state
, Taxon taxon
, List
<DescriptionElementBase
> specimenFacts
) {
365 CdmLightExportTable table
= CdmLightExportTable
.SPECIMEN_FACT
;
367 for (DescriptionElementBase element
: specimenFacts
){
369 String
[] csvLine
= new String
[table
.getSize()];
370 csvLine
[table
.getIndex(CdmLightExportTable
.FACT_ID
)] = getId(state
, element
);
371 csvLine
[table
.getIndex(CdmLightExportTable
.TAXON_FK
)] = getId(state
, taxon
);
372 handleSource(state
, element
, table
);
373 csvLine
[table
.getIndex(CdmLightExportTable
.SPECIMEN_NOTES
)] = createAnnotationsString(element
.getAnnotations());
375 if (element
instanceof IndividualsAssociation
){
377 IndividualsAssociation indAssociation
= (IndividualsAssociation
)element
;
378 if (state
.getSpecimenFromStore(indAssociation
.getAssociatedSpecimenOrObservation().getId()) == null){
379 SpecimenOrObservationBase
<?
> specimenBase
= HibernateProxyHelper
.deproxy(indAssociation
.getAssociatedSpecimenOrObservation());
381 if (specimenBase
instanceof DerivedUnit
){
382 DerivedUnit derivedUnit
= (DerivedUnit
)specimenBase
;
383 handleSpecimen(state
, derivedUnit
);
384 csvLine
[table
.getIndex(CdmLightExportTable
.SPECIMEN_FK
)] = getId(state
, indAssociation
.getAssociatedSpecimenOrObservation());
386 //field units are not supported
387 state
.getResult().addError("The associated Specimen of taxon " + taxon
.getUuid() + " is not an DerivedUnit. Could not be exported.");
390 } else if (element
instanceof TextData
){
391 TextData textData
= HibernateProxyHelper
.deproxy(element
, TextData
.class);
392 csvLine
[table
.getIndex(CdmLightExportTable
.SPECIMEN_DESCRIPTION
)] = createMultilanguageString(textData
.getMultilanguageText());
394 state
.getProcessor().put(table
, element
, csvLine
);
395 } catch (Exception e
) {
396 state
.getResult().addException(e
, "An unexpected error occurred when handling single specimen fact " +
397 cdmBaseStr(element
) + ": " + e
.getMessage());
403 * @param multilanguageText
406 private String
createMultilanguageString(Map
<Language
, LanguageString
> multilanguageText
) {
408 int index
= multilanguageText
.size();
409 for(LanguageString langString
: multilanguageText
.values()){
410 text
+= langString
.getText();
424 private String
createAnnotationsString(Set
<Annotation
> annotations
) {
425 StringBuffer strBuff
= new StringBuffer();
427 for (Annotation ann
:annotations
){
428 if (ann
.getAnnotationType() == null ||!ann
.getAnnotationType().equals(AnnotationType
.TECHNICAL())){
429 strBuff
.append(ann
.getText());
430 strBuff
.append("; ");
434 if (strBuff
.length() > 2){
435 return strBuff
.substring(0, strBuff
.length()-2);
446 private void handleSource(CdmLightExportState state
, DescriptionElementBase element
, CdmLightExportTable factsTable
) {
447 CdmLightExportTable table
= CdmLightExportTable
.FACT_SOURCES
;
448 Set
<DescriptionElementSource
> sources
= element
.getSources();
449 for (DescriptionElementSource source
: sources
){
451 String
[] csvLine
= new String
[table
.getSize()];
452 Reference ref
= source
.getCitation();
453 if ((ref
== null) && (source
.getNameUsedInSource() == null)){
457 if (state
.getReferenceFromStore(ref
.getId()) == null){
458 handleReference(state
, ref
);
459 csvLine
[table
.getIndex(CdmLightExportTable
.REFERENCE_FK
)] = getId(state
, ref
);
462 csvLine
[table
.getIndex(CdmLightExportTable
.FACT_FK
)] = getId(state
, element
);
464 csvLine
[table
.getIndex(CdmLightExportTable
.NAME_IN_SOURCE_FK
)] = getId(state
, source
.getNameUsedInSource());
465 csvLine
[table
.getIndex(CdmLightExportTable
.FACT_TYPE
)] = factsTable
.getTableName();
466 if ( StringUtils
.isBlank(csvLine
[table
.getIndex(CdmLightExportTable
.REFERENCE_FK
)]) && StringUtils
.isBlank(csvLine
[table
.getIndex(CdmLightExportTable
.NAME_IN_SOURCE_FK
)])){
469 state
.getProcessor().put(table
, source
, csvLine
);
470 } catch (Exception e
) {
471 state
.getResult().addException(e
, "An unexpected error occurred when handling single source " +
472 cdmBaseStr(element
) + ": " + e
.getMessage());
480 * @param distributionFacts
482 private void handleDistributionFacts(CdmLightExportState state
, Taxon taxon
, List
<DescriptionElementBase
> distributionFacts
) {
483 CdmLightExportTable table
= CdmLightExportTable
.GEOGRAPHIC_AREA_FACT
;
485 for (DescriptionElementBase element
: distributionFacts
){
487 if (element
instanceof Distribution
){
488 String
[] csvLine
= new String
[table
.getSize()];
489 Distribution distribution
= (Distribution
)element
;
490 csvLine
[table
.getIndex(CdmLightExportTable
.FACT_ID
)] = getId(state
, element
);
491 handleSource(state
, element
, table
);
492 csvLine
[table
.getIndex(CdmLightExportTable
.TAXON_FK
)] = getId(state
, taxon
);
493 if (distribution
.getArea() != null){
494 csvLine
[table
.getIndex(CdmLightExportTable
.AREA_LABEL
)] = distribution
.getArea().getLabel();
496 if (distribution
.getStatus() != null){
497 csvLine
[table
.getIndex(CdmLightExportTable
.STATUS_LABEL
)] = distribution
.getStatus().getLabel();
499 state
.getProcessor().put(table
, distribution
, csvLine
);
501 state
.getResult().addError("The distribution description for the taxon " + taxon
.getUuid() + " is not of type distribution. Could not be exported. UUID of the description element: " + element
.getUuid());
503 } catch (Exception e
) {
504 state
.getResult().addException(e
, "An unexpected error occurred when handling single distribution " +
505 cdmBaseStr(element
) + ": " + e
.getMessage());
512 * @param commonNameFacts
514 private void handleCommonNameFacts(CdmLightExportState state
, Taxon taxon
, List
<DescriptionElementBase
> commonNameFacts
) {
515 CdmLightExportTable table
= CdmLightExportTable
.COMMON_NAME_FACT
;
517 for (DescriptionElementBase element
: commonNameFacts
){
519 if (element
instanceof CommonTaxonName
){
520 String
[] csvLine
= new String
[table
.getSize()];
521 CommonTaxonName commonName
= (CommonTaxonName
)element
;
522 csvLine
[table
.getIndex(CdmLightExportTable
.FACT_ID
)] = getId(state
, element
);
523 handleSource(state
, element
, table
);
524 csvLine
[table
.getIndex(CdmLightExportTable
.TAXON_FK
)] = getId(state
, taxon
);
525 if (commonName
.getName() != null){csvLine
[table
.getIndex(CdmLightExportTable
.FACT_TEXT
)] = commonName
.getName();}
526 if (commonName
.getLanguage() != null){csvLine
[table
.getIndex(CdmLightExportTable
.LANGUAGE
)] = commonName
.getLanguage().getLabel();}
527 if (commonName
.getArea() != null){ csvLine
[table
.getIndex(CdmLightExportTable
.AREA_LABEL
)] = commonName
.getArea().getLabel();}
528 state
.getProcessor().put(table
, commonName
, csvLine
);
530 state
.getResult().addError("The distribution description for the taxon " + taxon
.getUuid() + " is not of type distribution. Could not be exported. UUID of the description element: " + element
.getUuid());
532 } catch (Exception e
) {
533 state
.getResult().addException(e
, "An unexpected error occurred when handling single common name " +
534 cdmBaseStr(element
) + ": " + e
.getMessage());
543 private String
getTitleCache(IIdentifiableEntity identEntity
) {
544 if (identEntity
== null){
548 return identEntity
.getTitleCache();
556 private String
getId(CdmLightExportState state
, ICdmBase cdmBase
) {
557 if (cdmBase
== null){
560 //TODO make configurable
561 return cdmBase
.getUuid().toString();
568 private void handleSynonym(CdmLightExportState state
, Synonym syn
) {
570 TaxonName name
= syn
.getName();
571 handleName(state
, name
);
573 CdmLightExportTable table
= CdmLightExportTable
.SYNONYM
;
574 String
[] csvLine
= new String
[table
.getSize()];
576 csvLine
[table
.getIndex(CdmLightExportTable
.SYNONYM_ID
)] = getId(state
, syn
);
577 csvLine
[table
.getIndex(CdmLightExportTable
.TAXON_FK
)] = getId(state
, syn
.getAcceptedTaxon());
578 csvLine
[table
.getIndex(CdmLightExportTable
.NAME_FK
)] = getId(state
, name
);
579 csvLine
[table
.getIndex(CdmLightExportTable
.SEC_REFERENCE_FK
)] = getId(state
, syn
.getSec());
580 csvLine
[table
.getIndex(CdmLightExportTable
.SEC_REFERENCE
)] = getTitleCache(syn
.getSec());
582 state
.getProcessor().put(table
, syn
, csvLine
);
583 } catch (Exception e
) {
584 state
.getResult().addException(e
, "An unexpected error occurred when handling synonym " +
585 cdmBaseStr(syn
) + ": " + e
.getMessage());
593 private void handleName(CdmLightExportState state
, TaxonName name
) {
598 Rank rank
= name
.getRank();
599 CdmLightExportTable table
= CdmLightExportTable
.SCIENTIFIC_NAME
;
600 name
= HibernateProxyHelper
.deproxy(name
);
601 String
[] csvLine
= new String
[table
.getSize()];
603 csvLine
[table
.getIndex(CdmLightExportTable
.NAME_ID
)] = getId(state
, name
);
604 if (name
.getLsid() != null){
605 csvLine
[table
.getIndex(CdmLightExportTable
.LSID
)] = name
.getLsid().getLsid();
607 csvLine
[table
.getIndex(CdmLightExportTable
.LSID
)] = "";
610 handleIdentifier(state
, name
);
611 handleDescriptions(state
, name
);
613 csvLine
[table
.getIndex(CdmLightExportTable
.RANK
)] = getTitleCache(rank
);
615 csvLine
[table
.getIndex(CdmLightExportTable
.RANK_SEQUENCE
)] = String
.valueOf(rank
.getOrderIndex());
616 if (rank
.isInfraGeneric()){
618 csvLine
[table
.getIndex(CdmLightExportTable
.INFRAGENERIC_RANK
)] = name
.getRank().getInfraGenericMarker();
619 } catch (UnknownCdmTypeException e
) {
620 state
.getResult().addError("Infrageneric marker expected but not available for rank " + name
.getRank().getTitleCache());
623 if (rank
.isInfraSpecific()){
624 csvLine
[table
.getIndex(CdmLightExportTable
.INFRASPECIFIC_RANK
)] = name
.getRank().getAbbreviation();
627 csvLine
[table
.getIndex(CdmLightExportTable
.RANK_SEQUENCE
)] = "";
629 if (name
.isProtectedTitleCache()){
630 csvLine
[table
.getIndex(CdmLightExportTable
.FULL_NAME_WITH_AUTHORS
)] =name
.getTitleCache();
632 //TODO: adapt the tropicos titlecache creation
633 csvLine
[table
.getIndex(CdmLightExportTable
.FULL_NAME_WITH_AUTHORS
)] = name
.getTitleCache();
635 csvLine
[table
.getIndex(CdmLightExportTable
.FULL_NAME_NO_AUTHORS
)] = name
.getNameCache();
636 csvLine
[table
.getIndex(CdmLightExportTable
.GENUS_UNINOMIAL
)] = name
.getGenusOrUninomial();
638 csvLine
[table
.getIndex(CdmLightExportTable
.INFRAGENERIC_EPITHET
)] = name
.getInfraGenericEpithet();
639 csvLine
[table
.getIndex(CdmLightExportTable
.SPECIFIC_EPITHET
)] = name
.getSpecificEpithet();
641 csvLine
[table
.getIndex(CdmLightExportTable
.INFRASPECIFIC_EPITHET
)] = name
.getInfraSpecificEpithet();
642 csvLine
[table
.getIndex(CdmLightExportTable
.BAS_AUTHORTEAM_FK
)] = getId(state
,name
.getBasionymAuthorship());
643 if (name
.getBasionymAuthorship() != null){
644 if (state
.getAuthorFromStore(name
.getBasionymAuthorship().getId()) == null) {
645 handleAuthor(state
, name
.getBasionymAuthorship());
648 csvLine
[table
.getIndex(CdmLightExportTable
.BAS_EX_AUTHORTEAM_FK
)] = getId(state
, name
.getExBasionymAuthorship());
649 if (name
.getExBasionymAuthorship() != null){
650 if (state
.getAuthorFromStore(name
.getExBasionymAuthorship().getId()) == null) {
651 handleAuthor(state
, name
.getExBasionymAuthorship());
655 csvLine
[table
.getIndex(CdmLightExportTable
.COMB_AUTHORTEAM_FK
)] = getId(state
,name
.getCombinationAuthorship());
656 if (name
.getCombinationAuthorship() != null){
657 if (state
.getAuthorFromStore(name
.getCombinationAuthorship().getId()) == null) {
658 handleAuthor(state
, name
.getCombinationAuthorship());
661 csvLine
[table
.getIndex(CdmLightExportTable
.COMB_EX_AUTHORTEAM_FK
)] = getId(state
, name
.getExCombinationAuthorship());
662 if (name
.getExCombinationAuthorship() != null){
663 if (state
.getAuthorFromStore(name
.getExCombinationAuthorship().getId()) == null) {
664 handleAuthor(state
, name
.getExCombinationAuthorship());
669 csvLine
[table
.getIndex(CdmLightExportTable
.AUTHOR_TEAM_STRING
)] = name
.getAuthorshipCache();
671 Reference nomRef
= (Reference
)name
.getNomenclaturalReference();
674 if (state
.getReferenceFromStore(nomRef
.getId()) == null){
675 handleReference(state
, nomRef
);
677 csvLine
[table
.getIndex(CdmLightExportTable
.REFERENCE_FK
)] = getId(state
, nomRef
);
678 csvLine
[table
.getIndex(CdmLightExportTable
.PUBLICATION_TYPE
)] = nomRef
.getType().name();
679 if (nomRef
.getVolume() != null){
680 csvLine
[table
.getIndex(CdmLightExportTable
.VOLUME_ISSUE
)] = nomRef
.getVolume();
681 csvLine
[table
.getIndex(CdmLightExportTable
.COLLATION
)] = createCollatation(name
);
683 if (nomRef
.getDatePublished() != null){
684 csvLine
[table
.getIndex(CdmLightExportTable
.DATE_PUBLISHED
)] = nomRef
.getTimePeriodPublishedString();
685 csvLine
[table
.getIndex(CdmLightExportTable
.YEAR_PUBLISHED
)] = nomRef
.getDatePublished().getYear();
686 csvLine
[table
.getIndex(CdmLightExportTable
.VERBATIM_DATE
)] = null;
688 if (name
.getNomenclaturalMicroReference() != null){
689 csvLine
[table
.getIndex(CdmLightExportTable
.DETAIL
)] = name
.getNomenclaturalMicroReference();
691 nomRef
= HibernateProxyHelper
.deproxy(nomRef
);
692 if (nomRef
.getInReference() != null){
693 Reference inReference
= nomRef
.getInReference();
694 if (inReference
.getDatePublished() != null && nomRef
.getDatePublished() == null){
695 csvLine
[table
.getIndex(CdmLightExportTable
.DATE_PUBLISHED
)] = inReference
.getDatePublishedString();
696 csvLine
[table
.getIndex(CdmLightExportTable
.YEAR_PUBLISHED
)] = inReference
.getDatePublished().getYear();
698 if (nomRef
.getVolume() == null && inReference
.getVolume() != null){
699 csvLine
[table
.getIndex(CdmLightExportTable
.VOLUME_ISSUE
)] = inReference
.getVolume();
700 csvLine
[table
.getIndex(CdmLightExportTable
.COLLATION
)] = createCollatation(name
);
702 if (inReference
.getInReference() != null){
703 inReference
= inReference
.getInReference();
705 if (inReference
.getAbbrevTitle() == null){
706 csvLine
[table
.getIndex(CdmLightExportTable
.ABBREV_TITLE
)] = CdmUtils
.Nz(inReference
.getAbbrevTitleCache());
708 csvLine
[table
.getIndex(CdmLightExportTable
.ABBREV_TITLE
)] = CdmUtils
.Nz(inReference
.getAbbrevTitle());
710 if (inReference
.getTitle() == null){
711 csvLine
[table
.getIndex(CdmLightExportTable
.FULL_TITLE
)] = CdmUtils
.Nz(inReference
.getTitleCache());
713 csvLine
[table
.getIndex(CdmLightExportTable
.FULL_TITLE
)] = CdmUtils
.Nz(inReference
.getTitle());
717 TeamOrPersonBase
<?
> author
= inReference
.getAuthorship();
718 if (author
!= null && (nomRef
.isOfType(ReferenceType
.BookSection
) || nomRef
.isOfType(ReferenceType
.Section
))){
719 csvLine
[table
.getIndex(CdmLightExportTable
.ABBREV_REF_AUTHOR
)] = CdmUtils
.Nz(author
.getNomenclaturalTitle());
720 csvLine
[table
.getIndex(CdmLightExportTable
.FULL_REF_AUTHOR
)] = CdmUtils
.Nz(author
.getTitleCache());
722 csvLine
[table
.getIndex(CdmLightExportTable
.ABBREV_REF_AUTHOR
)] = "";
723 csvLine
[table
.getIndex(CdmLightExportTable
.FULL_REF_AUTHOR
)] = "";
726 if (nomRef
.getAbbrevTitle() == null){
727 csvLine
[table
.getIndex(CdmLightExportTable
.ABBREV_TITLE
)] = CdmUtils
.Nz(nomRef
.getAbbrevTitleCache());
729 csvLine
[table
.getIndex(CdmLightExportTable
.ABBREV_TITLE
)] = CdmUtils
.Nz(nomRef
.getAbbrevTitle());
731 if (nomRef
.getTitle() == null){
732 csvLine
[table
.getIndex(CdmLightExportTable
.FULL_TITLE
)] = CdmUtils
.Nz(nomRef
.getTitleCache());
734 csvLine
[table
.getIndex(CdmLightExportTable
.FULL_TITLE
)] = CdmUtils
.Nz(nomRef
.getTitle());
736 TeamOrPersonBase
<?
> author
= nomRef
.getAuthorship();
737 if (author
!= null ){
738 csvLine
[table
.getIndex(CdmLightExportTable
.ABBREV_REF_AUTHOR
)] = CdmUtils
.Nz(author
.getNomenclaturalTitle());
739 csvLine
[table
.getIndex(CdmLightExportTable
.FULL_REF_AUTHOR
)] = CdmUtils
.Nz(author
.getTitleCache());
741 csvLine
[table
.getIndex(CdmLightExportTable
.ABBREV_REF_AUTHOR
)] = "";
742 csvLine
[table
.getIndex(CdmLightExportTable
.FULL_REF_AUTHOR
)] = "";
747 csvLine
[table
.getIndex(CdmLightExportTable
.PUBLICATION_TYPE
)] = "";
760 Set
<TaxonNameDescription
> descriptions
= name
.getDescriptions();
761 String protologueUriString
= extractURIs(state
, descriptions
, Feature
.PROTOLOGUE());
763 csvLine
[table
.getIndex(CdmLightExportTable
.PROTOLOGUE_URI
)] = protologueUriString
;
765 if (name
.getStatus() == null || name
.getStatus().isEmpty()){
766 csvLine
[table
.getIndex(CdmLightExportTable
.NOM_STATUS
)] = "";
767 csvLine
[table
.getIndex(CdmLightExportTable
.NOM_STATUS_ABBREV
)] = "";
770 String statusStringAbbrev
= extractStatusString(state
, name
, true);
771 String statusString
= extractStatusString(state
, name
, false);
773 csvLine
[table
.getIndex(CdmLightExportTable
.NOM_STATUS
)] = statusString
.trim();
774 csvLine
[table
.getIndex(CdmLightExportTable
.NOM_STATUS_ABBREV
)] = statusStringAbbrev
.trim();
777 HomotypicalGroup group
=name
.getHomotypicalGroup();
779 if (state
.getHomotypicalGroupFromStore(group
.getId()) == null){
780 handleHomotypicalGroup(state
, group
);
782 csvLine
[table
.getIndex(CdmLightExportTable
.HOMOTYPIC_GROUP_FK
)] = getId(state
, group
);
783 List
<TaxonName
> typifiedNames
= new ArrayList
<>();
784 typifiedNames
.addAll(group
.getTypifiedNames());
785 Collections
.sort(typifiedNames
, new HomotypicalGroupNameComparator(null, true));
786 Integer seqNumber
= typifiedNames
.indexOf(name
);
787 csvLine
[table
.getIndex(CdmLightExportTable
.HOMOTYPIC_GROUP_SEQ
)] = String
.valueOf(seqNumber
);
788 state
.getProcessor().put(table
, name
, csvLine
);
809 HomotypicGroupSequenceNumber
814 } catch (Exception e
) {
815 state
.getResult().addException(e
, "An unexpected error occurred when handling synonym " +
816 cdmBaseStr(name
) + ": " + e
.getMessage());
823 private String
createCollatation(TaxonName name
) {
824 String collation
= "";
825 if (name
.getNomenclaturalReference() != null){
826 Reference ref
= (Reference
) name
.getNomenclaturalReference();
827 collation
= getVolume(ref
);
829 if (name
.getNomenclaturalMicroReference() != null){
830 if (!StringUtils
.isBlank(collation
)){
833 collation
+=name
.getNomenclaturalMicroReference();
840 * @param nomenclaturalReference
843 private String
getVolume(Reference reference
) {
844 if (reference
.getVolume() != null){
845 return reference
.getVolume();
846 }else if (reference
.getInReference() != null){
847 if (reference
.getInReference().getVolume() != null){
848 return reference
.getInReference().getVolume();
858 private void handleIdentifier(CdmLightExportState state
, TaxonName name
) {
859 CdmLightExportTable table
= CdmLightExportTable
.IDENTIFIER
;
862 Set
<String
> IPNIidentifiers
= name
.getIdentifiers(DefinedTerm
.IPNI_NAME_IDENTIFIER());
863 Set
<String
> tropicosIdentifiers
= name
.getIdentifiers(DefinedTerm
.TROPICOS_NAME_IDENTIFIER());
864 Set
<String
> WFOIdentifiers
= name
.getIdentifiers(DefinedTerm
.uuidWfoNameIdentifier
);
865 if (!IPNIidentifiers
.isEmpty()){
866 csvLine
= new String
[table
.getSize()];
867 csvLine
[table
.getIndex(CdmLightExportTable
.NAME_FK
)] = getId( state
, name
);
868 csvLine
[table
.getIndex(CdmLightExportTable
.IDENTIFIER_TYPE
)] = IPNI_NAME_IDENTIFIER
;
869 csvLine
[table
.getIndex(CdmLightExportTable
.IDENTIFIER_IDS
)] = extractIdentifier(IPNIidentifiers
);
870 state
.getProcessor().put(table
, name
, csvLine
);
872 if (!tropicosIdentifiers
.isEmpty()){
873 csvLine
= new String
[table
.getSize()];
874 csvLine
[table
.getIndex(CdmLightExportTable
.NAME_FK
)] = getId( state
, name
);
875 csvLine
[table
.getIndex(CdmLightExportTable
.IDENTIFIER_TYPE
)] = TROPICOS_NAME_IDENTIFIER
;
876 csvLine
[table
.getIndex(CdmLightExportTable
.IDENTIFIER_IDS
)] = extractIdentifier(tropicosIdentifiers
);
877 state
.getProcessor().put(table
, name
, csvLine
);
879 if (!WFOIdentifiers
.isEmpty()){
880 csvLine
= new String
[table
.getSize()];
881 csvLine
[table
.getIndex(CdmLightExportTable
.NAME_FK
)] = getId( state
, name
);
882 csvLine
[table
.getIndex(CdmLightExportTable
.IDENTIFIER_TYPE
)] = WFO_NAME_IDENTIFIER
;
883 csvLine
[table
.getIndex(CdmLightExportTable
.IDENTIFIER_IDS
)] = extractIdentifier(WFOIdentifiers
);
884 state
.getProcessor().put(table
, name
, csvLine
);
886 } catch (Exception e
) {
887 state
.getResult().addException(e
, "An unexpected error occurred when handling identifiers for " +
888 cdmBaseStr(name
) + ": " + e
.getMessage());
894 * @param tropicosIdentifiers
896 private String
extractIdentifier(Set
<String
> identifierSet
) {
898 String identifierString
= "";
899 for (String identifier
: identifierSet
){
900 if (!StringUtils
.isBlank(identifierString
)){
901 identifierString
+= ", ";
903 identifierString
+= identifier
;
906 return identifierString
;
911 * @param descriptions
914 private String
extractURIs(CdmLightExportState state
,
915 Set
<?
extends DescriptionBase
<?
>> descriptionsSet
, Feature feature
) {
916 String mediaUriString
= "";
917 SpecimenDescription specimenDescription
;
918 TaxonDescription taxonDescription
;
919 TaxonNameDescription nameDescription
;
920 Set
<DescriptionElementBase
> elements
= new HashSet
<>();
921 for (DescriptionBase
<?
> description
: descriptionsSet
){
923 if (!description
.getElements().isEmpty()){
924 if (description
instanceof SpecimenDescription
){
925 specimenDescription
= (SpecimenDescription
)description
;
926 elements
= specimenDescription
.getElements();
927 }else if (description
instanceof TaxonDescription
){
928 taxonDescription
= (TaxonDescription
) description
;
929 elements
= taxonDescription
.getElements();
930 } else if (description
instanceof TaxonNameDescription
){
931 nameDescription
= (TaxonNameDescription
) description
;
932 elements
= nameDescription
.getElements();
935 for (DescriptionElementBase element
: elements
){
936 Feature entityFeature
= HibernateProxyHelper
.deproxy(element
.getFeature());
937 if (entityFeature
.equals(feature
)){
938 if (!element
.getMedia().isEmpty()){
939 List
<Media
> media
= element
.getMedia();
940 for (Media mediaElement
: media
){
941 Iterator
<MediaRepresentation
> it
= mediaElement
.getRepresentations().iterator();
942 mediaUriString
= extractMediaUris(it
);
948 } catch (Exception e
) {
949 state
.getResult().addException(e
, "An unexpected error occurred when extracting media URIs for " +
950 cdmBaseStr(description
) + ": " + e
.getMessage());
953 return mediaUriString
;
958 * @param basionymAuthorship
960 private void handleAuthor(CdmLightExportState state
, TeamOrPersonBase
<?
> author
) {
962 if (state
.getAuthorFromStore(author
.getId()) != null){
965 state
.addAuthorToStore(author
);
966 CdmLightExportTable table
= CdmLightExportTable
.NOMENCLATURAL_AUTHOR
;
967 String
[] csvLine
= new String
[table
.getSize()];
968 CdmLightExportTable tableAuthorRel
= CdmLightExportTable
.NOMENCLATURAL_AUTHOR_TEAM_RELATION
;
969 String
[] csvLineRel
= new String
[tableAuthorRel
.getSize()];
970 String
[] csvLineMember
= new String
[table
.getSize()];
971 csvLine
[table
.getIndex(CdmLightExportTable
.AUTHOR_ID
)] = getId(state
, author
);
972 csvLine
[table
.getIndex(CdmLightExportTable
.ABBREV_AUTHOR
)] = author
.getNomenclaturalTitle();
973 csvLine
[table
.getIndex(CdmLightExportTable
.AUTHOR_TITLE
)] = author
.getTitleCache();
974 author
= HibernateProxyHelper
.deproxy(author
);
975 if (author
instanceof Person
){
976 Person authorPerson
= (Person
)author
;
977 csvLine
[table
.getIndex(CdmLightExportTable
.AUTHOR_FIRST_NAME
)] = authorPerson
.getFirstname();
978 csvLine
[table
.getIndex(CdmLightExportTable
.AUTHOR_LASTNAME
)] = authorPerson
.getLastname();
979 csvLine
[table
.getIndex(CdmLightExportTable
.AUTHOR_PREFIX
)] = authorPerson
.getPrefix();
980 csvLine
[table
.getIndex(CdmLightExportTable
.AUTHOR_SUFFIX
)] = authorPerson
.getSuffix();
982 // create an entry in rel table and all members in author table, check whether the team members already in author table
984 Team authorTeam
= (Team
)author
;
986 for (Person member
: authorTeam
.getTeamMembers()){
987 csvLineRel
= new String
[tableAuthorRel
.getSize()];
988 csvLineRel
[tableAuthorRel
.getIndex(CdmLightExportTable
.AUTHOR_TEAM_FK
)] = getId(state
, authorTeam
);
989 csvLineRel
[tableAuthorRel
.getIndex(CdmLightExportTable
.AUTHOR_FK
)] = getId(state
, member
);
990 csvLineRel
[tableAuthorRel
.getIndex(CdmLightExportTable
.AUTHOR_TEAM_SEQ_NUMBER
)] = String
.valueOf(index
);
991 state
.getProcessor().put(tableAuthorRel
, authorTeam
.getId() +":" +member
.getId(), csvLineRel
);
993 if (state
.getAuthorFromStore(member
.getId()) == null){
994 state
.addAuthorToStore(member
);
995 csvLineMember
= new String
[table
.getSize()];
996 csvLineMember
[table
.getIndex(CdmLightExportTable
.AUTHOR_ID
)] = getId(state
, member
);
997 csvLineMember
[table
.getIndex(CdmLightExportTable
.ABBREV_AUTHOR
)] = member
.getNomenclaturalTitle();
998 csvLineMember
[table
.getIndex(CdmLightExportTable
.AUTHOR_TITLE
)] = member
.getTitleCache();
999 csvLineMember
[table
.getIndex(CdmLightExportTable
.AUTHOR_FIRST_NAME
)] = member
.getFirstname();
1000 csvLineMember
[table
.getIndex(CdmLightExportTable
.AUTHOR_LASTNAME
)] = member
.getLastname();
1001 csvLineMember
[table
.getIndex(CdmLightExportTable
.AUTHOR_PREFIX
)] = member
.getPrefix();
1002 csvLineMember
[table
.getIndex(CdmLightExportTable
.AUTHOR_SUFFIX
)] = member
.getSuffix();
1003 state
.getProcessor().put(table
, member
, csvLineMember
);
1009 state
.getProcessor().put(table
, author
, csvLine
);
1010 } catch (Exception e
) {
1011 state
.getResult().addException(e
, "An unexpected error occurred when handling author " +
1012 cdmBaseStr(author
) + ": " + e
.getMessage());
1019 * @param statusString
1022 private String
extractStatusString(CdmLightExportState state
, TaxonName name
, boolean abbrev
) {
1024 Set
<NomenclaturalStatus
> status
= name
.getStatus();
1025 if (status
.isEmpty()){
1028 String statusString
= "";
1029 for (NomenclaturalStatus nameStatus
: status
){
1030 if (nameStatus
!= null){
1032 if (nameStatus
.getType() != null){
1033 statusString
+= nameStatus
.getType().getIdInVocabulary();
1036 if (nameStatus
.getType() != null){
1037 statusString
+= nameStatus
.getType().getTitleCache();
1042 if (nameStatus
.getRuleConsidered() != null && !StringUtils
.isBlank(nameStatus
.getRuleConsidered())){
1043 statusString
+= " " + nameStatus
.getRuleConsidered();
1045 if (nameStatus
.getCitation() != null){
1046 statusString
+= " " + nameStatus
.getCitation().getTitleCache();
1048 if (nameStatus
.getCitationMicroReference() != null && !StringUtils
.isBlank(nameStatus
.getCitationMicroReference())){
1049 statusString
+= " " + nameStatus
.getCitationMicroReference();
1052 statusString
+= " ";
1055 return statusString
;
1056 } catch (Exception e
) {
1057 state
.getResult().addException(e
, "An unexpected error occurred when extracting status string for " +
1058 cdmBaseStr(name
) + ": " + e
.getMessage());
1066 private void handleHomotypicalGroup(CdmLightExportState state
, HomotypicalGroup group
) {
1068 state
.addHomotypicalGroupToStore(group
);
1069 CdmLightExportTable table
= CdmLightExportTable
.HOMOTYPIC_GROUP
;
1070 String
[] csvLine
= new String
[table
.getSize()];
1072 csvLine
[table
.getIndex(CdmLightExportTable
.HOMOTYPIC_GROUP_ID
)] = getId(state
, group
);
1073 List
<TaxonName
> typifiedNames
= new ArrayList
<>();
1074 typifiedNames
.addAll(group
.getTypifiedNames());
1075 Collections
.sort(typifiedNames
, new HomotypicalGroupNameComparator(null, true));
1076 String typifiedNamesString
= "";
1077 for (TaxonName name
: typifiedNames
){
1078 //Concatenated output string for homotypic group (names and citations) + status + some name relations (e.g. “non”)
1079 //TODO: nameRelations, which and how to display
1082 typifiedNamesString
+= name
.getTitleCache()+ extractStatusString(state
, name
, true) + "; ";
1084 typifiedNamesString
= typifiedNamesString
.substring(0, typifiedNamesString
.length()-2);
1085 if (typifiedNamesString
!= null){
1086 csvLine
[table
.getIndex(CdmLightExportTable
.HOMOTYPIC_GROUP_STRING
)] = typifiedNamesString
.trim();
1088 csvLine
[table
.getIndex(CdmLightExportTable
.HOMOTYPIC_GROUP_STRING
)] = "";
1090 Set
<TypeDesignationBase
> typeDesigantions
= group
.getTypeDesignations();
1091 List
<TypeDesignationBase
> designationList
= new ArrayList
<>();
1092 designationList
.addAll(typeDesigantions
);
1093 Collections
.sort(designationList
, new TypeComparator());
1094 StringBuffer typeDesignationString
= new StringBuffer();
1095 for (TypeDesignationBase typeDesignation
: typeDesigantions
){
1096 if (typeDesignation
!= null && typeDesignation
.getTypeStatus() != null){
1097 typeDesignationString
.append(typeDesignation
.getTypeStatus().getTitleCache() + ": ");
1099 if (typeDesignation
instanceof SpecimenTypeDesignation
){
1100 if (((SpecimenTypeDesignation
)typeDesignation
).getTypeSpecimen() != null){
1101 typeDesignationString
.append(((SpecimenTypeDesignation
)typeDesignation
).getTypeSpecimen().getTitleCache());
1102 handleSpecimen(state
, ((SpecimenTypeDesignation
)typeDesignation
).getTypeSpecimen());
1105 if (((NameTypeDesignation
)typeDesignation
).getTypeName() != null){
1106 typeDesignationString
.append(((NameTypeDesignation
)typeDesignation
).getTypeName().getTitleCache());
1109 if(typeDesignation
.getCitation() != null ){
1110 typeDesignationString
.append(", "+typeDesignation
.getCitation().getTitleCache());
1115 1. Status der Typen: a) holo, lecto, neo, syn, b) epi, paralecto, c) para (wenn überhaupt) – die jeweiligen iso immer direct mit dazu
1120 Aufbau der Typusinformationen:
1121 Land: Lokalität mit Höhe und Koordinaten; Datum; Sammler Nummer (Herbar/Barcode, Typusart; Herbar/Barcode, Typusart …)
1125 String typeDesignations
= typeDesignationString
.toString();
1126 if (typeDesignations
!= null){
1127 csvLine
[table
.getIndex(CdmLightExportTable
.TYPE_STRING
)] = typeDesignations
;
1129 csvLine
[table
.getIndex(CdmLightExportTable
.TYPE_STRING
)] = "";
1131 state
.getProcessor().put(table
, String
.valueOf(group
.getId()), csvLine
);
1132 } catch (Exception e
) {
1133 state
.getResult().addException(e
, "An unexpected error occurred when handling homotypic group " +
1134 cdmBaseStr(group
) + ": " + e
.getMessage());
1142 private String
getTropicosTitleCache(CdmLightExportState state
, TaxonName name
) {
1144 String basionymStart
= "(";
1145 String basionymEnd
= ") ";
1146 String exAuthorSeperator
= " ex ";
1147 TeamOrPersonBase
<?
> combinationAuthor
= name
.getCombinationAuthorship();
1148 TeamOrPersonBase
<?
> exCombinationAuthor
= name
.getExCombinationAuthorship();
1149 TeamOrPersonBase
<?
> basionymAuthor
= name
.getBasionymAuthorship();
1150 TeamOrPersonBase
<?
> exBasionymAuthor
= name
.getExBasionymAuthorship();
1152 String combinationAuthorString
= "";
1153 if (combinationAuthor
!= null){
1154 combinationAuthor
= HibernateProxyHelper
.deproxy(combinationAuthor
);
1155 if (combinationAuthor
instanceof Team
){
1156 combinationAuthorString
= createTropicosTeamTitle(combinationAuthor
);
1158 Person person
= HibernateProxyHelper
.deproxy(combinationAuthor
, Person
.class);
1159 combinationAuthorString
= createTropicosAuthorString(person
);
1162 String exCombinationAuthorString
= "";
1163 if (exCombinationAuthor
!= null){
1164 exCombinationAuthor
= HibernateProxyHelper
.deproxy(exCombinationAuthor
);
1165 if (exCombinationAuthor
instanceof Team
){
1166 exCombinationAuthorString
= createTropicosTeamTitle(exCombinationAuthor
);
1168 Person person
= HibernateProxyHelper
.deproxy(exCombinationAuthor
, Person
.class);
1169 exCombinationAuthorString
= createTropicosAuthorString(person
);
1173 String basionymAuthorString
= "";
1174 if (basionymAuthor
!= null){
1175 basionymAuthor
= HibernateProxyHelper
.deproxy(basionymAuthor
);
1176 if (basionymAuthor
instanceof Team
){
1177 basionymAuthorString
= createTropicosTeamTitle(basionymAuthor
);
1179 Person person
= HibernateProxyHelper
.deproxy(basionymAuthor
, Person
.class);
1180 basionymAuthorString
= createTropicosAuthorString(person
);
1184 String exBasionymAuthorString
= "";
1186 if (exBasionymAuthor
!= null){
1187 exBasionymAuthor
= HibernateProxyHelper
.deproxy(exBasionymAuthor
);
1188 if (exBasionymAuthor
instanceof Team
){
1189 exBasionymAuthorString
= createTropicosTeamTitle(exBasionymAuthor
);
1192 Person person
= HibernateProxyHelper
.deproxy(exBasionymAuthor
, Person
.class);
1193 exBasionymAuthorString
= createTropicosAuthorString(person
);
1196 String completeAuthorString
= name
.getNameCache() + " ";
1198 completeAuthorString
+= (!CdmUtils
.isBlank(exBasionymAuthorString
) || !CdmUtils
.isBlank(basionymAuthorString
)) ? basionymStart
: "";
1199 completeAuthorString
+= (!CdmUtils
.isBlank(exBasionymAuthorString
)) ?
(CdmUtils
.Nz(exBasionymAuthorString
) + exAuthorSeperator
): "" ;
1200 completeAuthorString
+= (!CdmUtils
.isBlank(basionymAuthorString
))? CdmUtils
.Nz(basionymAuthorString
):"";
1201 completeAuthorString
+= (!CdmUtils
.isBlank(exBasionymAuthorString
) || !CdmUtils
.isBlank(basionymAuthorString
)) ? basionymEnd
:"";
1202 completeAuthorString
+= (!CdmUtils
.isBlank(exCombinationAuthorString
)) ?
(CdmUtils
.Nz(exCombinationAuthorString
) + exAuthorSeperator
): "" ;
1203 completeAuthorString
+= (!CdmUtils
.isBlank(combinationAuthorString
))? CdmUtils
.Nz(combinationAuthorString
):"";
1206 return completeAuthorString
;
1207 } catch (Exception e
) {
1208 state
.getResult().addException(e
, "An unexpected error occurred when handling tropicos title cache for " +
1209 cdmBaseStr(name
) + ": " + e
.getMessage());
1215 * @param combinationAuthor
1218 private String
createTropicosTeamTitle(TeamOrPersonBase
<?
> combinationAuthor
) {
1219 String combinationAuthorString
;
1220 Team team
= HibernateProxyHelper
.deproxy(combinationAuthor
, Team
.class);
1221 Team tempTeam
= Team
.NewInstance();
1222 for (Person teamMember
:team
.getTeamMembers()){
1223 combinationAuthorString
= createTropicosAuthorString(teamMember
);
1224 Person tempPerson
= Person
.NewTitledInstance(combinationAuthorString
);
1225 tempTeam
.addTeamMember(tempPerson
);
1227 combinationAuthorString
= tempTeam
.generateTitle();
1228 return combinationAuthorString
;
1234 private String
createTropicosAuthorString(Person teamMember
) {
1235 String nomAuthorString
= "";
1236 String
[] splittedAuthorString
= null;
1237 if (teamMember
== null){
1238 return nomAuthorString
;
1241 if (teamMember
.getFirstname() != null){
1242 String firstNameString
= teamMember
.getFirstname().replaceAll("\\.", "\\. ");
1243 splittedAuthorString
= firstNameString
.split("\\s");
1244 for (String split
: splittedAuthorString
){
1245 if (!StringUtils
.isBlank(split
)){
1246 nomAuthorString
+= split
.substring(0, 1);
1247 nomAuthorString
+= ".";
1251 if (teamMember
.getLastname() != null){
1252 String lastNameString
= teamMember
.getLastname().replaceAll("\\.", "\\. ");
1253 splittedAuthorString
= lastNameString
.split("\\s");
1254 for (String split
: splittedAuthorString
){
1255 nomAuthorString
+= " " +split
;
1258 if (StringUtils
.isBlank(nomAuthorString
.trim())){
1259 if (teamMember
.getTitleCache() != null) {
1260 String titleCacheString
= teamMember
.getTitleCache().replaceAll("\\.", "\\. ");
1261 splittedAuthorString
= titleCacheString
.split("\\s");
1266 for (String split
: splittedAuthorString
){
1267 if ( index
< splittedAuthorString
.length
-1 && (split
.length()==1 || split
.endsWith("."))){
1268 nomAuthorString
+= split
;
1270 nomAuthorString
= nomAuthorString
+" "+ split
;
1275 return nomAuthorString
.trim();
1282 private void handleReference(CdmLightExportState state
, Reference reference
) {
1284 state
.addReferenceToStore(reference
);
1285 CdmLightExportTable table
= CdmLightExportTable
.REFERENCE
;
1287 String
[] csvLine
= new String
[table
.getSize()];
1288 csvLine
[table
.getIndex(CdmLightExportTable
.REFERENCE_ID
)] = getId(state
, reference
);
1289 //TODO short citations correctly
1290 String shortCitation
= createShortCitation(reference
); //Should be Author(year) like in Taxon.sec
1291 csvLine
[table
.getIndex(CdmLightExportTable
.BIBLIO_SHORT_CITATION
)] = shortCitation
;
1292 //TODO get preferred title
1293 csvLine
[table
.getIndex(CdmLightExportTable
.REF_TITLE
)] = reference
.getTitle();
1294 csvLine
[table
.getIndex(CdmLightExportTable
.ABBREV_REF_TITLE
)] = reference
.getAbbrevTitle();
1295 csvLine
[table
.getIndex(CdmLightExportTable
.DATE_PUBLISHED
)] = reference
.getDatePublishedString();
1297 csvLine
[table
.getIndex(CdmLightExportTable
.EDITION
)] = reference
.getEdition();
1298 csvLine
[table
.getIndex(CdmLightExportTable
.EDITOR
)] = reference
.getEditor();
1299 csvLine
[table
.getIndex(CdmLightExportTable
.ISBN
)] = reference
.getIsbn();
1300 csvLine
[table
.getIndex(CdmLightExportTable
.ISSN
)] = reference
.getIssn();
1301 csvLine
[table
.getIndex(CdmLightExportTable
.ORGANISATION
)] = reference
.getOrganization();
1302 csvLine
[table
.getIndex(CdmLightExportTable
.PAGES
)] = reference
.getPages();
1303 csvLine
[table
.getIndex(CdmLightExportTable
.PLACE_PUBLISHED
)] = reference
.getPlacePublished();
1304 csvLine
[table
.getIndex(CdmLightExportTable
.PUBLISHER
)] = reference
.getPublisher();
1305 csvLine
[table
.getIndex(CdmLightExportTable
.REF_ABSTRACT
)] = reference
.getReferenceAbstract();
1306 csvLine
[table
.getIndex(CdmLightExportTable
.SERIES_PART
)] = reference
.getSeriesPart();
1307 csvLine
[table
.getIndex(CdmLightExportTable
.VOLUME
)] = reference
.getVolume();
1308 csvLine
[table
.getIndex(CdmLightExportTable
.YEAR
)] = reference
.getYear();
1309 if ( reference
.getAuthorship() != null){
1310 csvLine
[table
.getIndex(CdmLightExportTable
.AUTHORSHIP_TITLE
)] = reference
.getAuthorship().getTitleCache();
1311 csvLine
[table
.getIndex(CdmLightExportTable
.AUTHOR_FK
)] = getId(state
,reference
.getAuthorship());
1314 csvLine
[table
.getIndex(CdmLightExportTable
.IN_REFERENCE
)] = getId(state
, reference
.getInReference());
1315 if (reference
.getInReference() != null && state
.getReferenceFromStore(reference
.getInReference().getId()) == null){
1316 handleReference(state
, reference
.getInReference());
1318 if ( reference
.getInstitution() != null){ csvLine
[table
.getIndex(CdmLightExportTable
.INSTITUTION
)] = reference
.getInstitution().getTitleCache();}
1319 if ( reference
.getLsid() != null){ csvLine
[table
.getIndex(CdmLightExportTable
.LSID
)] = reference
.getLsid().getLsid();}
1320 if ( reference
.getSchool() != null){ csvLine
[table
.getIndex(CdmLightExportTable
.SCHOOL
)] = reference
.getSchool().getTitleCache();}
1321 if ( reference
.getUri() != null){ csvLine
[table
.getIndex(CdmLightExportTable
.URI
)] = reference
.getUri().toString();}
1322 csvLine
[table
.getIndex(CdmLightExportTable
.REF_TYPE
)] = reference
.getType().getKey();
1324 state
.getProcessor().put(table
, reference
, csvLine
);
1325 } catch (Exception e
) {
1326 state
.getResult().addException(e
, "An unexpected error occurred when handling reference " +
1327 cdmBaseStr(reference
) + ": " + e
.getMessage());
1337 private String
createShortCitation(Reference reference
) {
1338 TeamOrPersonBase
<?
> authorship
= reference
.getAuthorship();
1339 String shortCitation
= "";
1340 if (authorship
== null) {
1343 authorship
= HibernateProxyHelper
.deproxy(authorship
);
1344 if (authorship
instanceof Person
){ shortCitation
= ((Person
)authorship
).getLastname();}
1345 else if (authorship
instanceof Team
){
1347 Team authorTeam
= HibernateProxyHelper
.deproxy(authorship
, Team
.class);
1350 for (Person teamMember
: authorTeam
.getTeamMembers()){
1352 String concat
= concatString(authorTeam
, authorTeam
.getTeamMembers(), index
);
1353 shortCitation
+= concat
+ teamMember
.getLastname();
1357 if (reference
.getYear() != null){
1358 shortCitation
= shortCitation
+ " (" + reference
.getYear() + ")";
1360 return shortCitation
;
1363 private static String
concatString(Team team
, List
<Person
> teamMembers
, int i
) {
1367 }else if (i
< teamMembers
.size() || ( team
.isHasMoreMembers() && i
== teamMembers
.size())){
1368 concat
= STD_TEAM_CONCATINATION
;
1370 concat
= FINAL_TEAM_CONCATINATION
;
1376 * TypeDesignation table
1379 * TypeVerbatimCitation
1381 * TypeDesignatedByString
1382 * TypeDesignatedByRef_Fk
1385 private void handleSpecimenTypeDesignations(CdmLightExportState state
, TaxonName name
){
1387 Set
<SpecimenTypeDesignation
> typeDesignations
= name
.getSpecimenTypeDesignations();
1388 CdmLightExportTable table
= CdmLightExportTable
.TYPE_DESIGNATION
;
1389 String nameId
= getId(state
, name
);
1390 String
[] csvLine
= new String
[table
.getSize()];
1391 for (SpecimenTypeDesignation specimenType
: typeDesignations
){
1392 csvLine
= new String
[table
.getSize()];
1393 DerivedUnit specimen
= specimenType
.getTypeSpecimen();
1394 if (state
.getSpecimenFromStore(specimen
.getId()) == null){
1395 handleSpecimen(state
, specimen
);
1397 csvLine
[table
.getIndex(CdmLightExportTable
.SPECIMEN_FK
)] = getId(state
, specimenType
.getTypeSpecimen());
1398 csvLine
[table
.getIndex(CdmLightExportTable
.NAME_FK
)] = nameId
;
1399 csvLine
[table
.getIndex(CdmLightExportTable
.TYPE_VERBATIM_CITATION
)] = specimenType
.getTypeSpecimen().generateTitle();
1400 //TODO: add link to existing Vorcabulary
1401 csvLine
[table
.getIndex(CdmLightExportTable
.TYPE_CATEGORY
)] = "";
1402 csvLine
[table
.getIndex(CdmLightExportTable
.TYPE_DESIGNATED_BY_STRING
)] = specimenType
.getCitation().getTitleCache();
1403 csvLine
[table
.getIndex(CdmLightExportTable
.TYPE_DESIGNATED_BY_REF_FK
)] = getId(state
, specimenType
.getCitation());
1405 } catch (Exception e
) {
1406 state
.getResult().addException(e
, "An unexpected error occurred when handling specimen type designations for " +
1407 cdmBaseStr(name
) + ": " + e
.getMessage());
1415 private void handleSpecimen(CdmLightExportState state
, DerivedUnit specimen
) {
1417 state
.addSpecimenToStore(specimen
);
1418 CdmLightExportTable table
= CdmLightExportTable
.SPECIMEN
;
1419 String specimenId
= getId(state
, specimen
);
1420 String
[] csvLine
= new String
[table
.getSize()];
1422 csvLine
[table
.getIndex(CdmLightExportTable
.SPECIMEN_ID
)] = specimenId
;
1423 csvLine
[table
.getIndex(CdmLightExportTable
.SPECIMEN_CITATION
)] = specimen
.getTitleCache();
1424 csvLine
[table
.getIndex(CdmLightExportTable
.SPECIMEN_IMAGE_URIS
)] = extractURIs(state
, specimen
.getDescriptions(), Feature
.IMAGE());
1425 if (specimen
.getCollection() != null){ csvLine
[table
.getIndex(CdmLightExportTable
.HERBARIUM_ABBREV
)] = specimen
.getCollection().getCode();}
1426 if (specimen
instanceof MediaSpecimen
){
1427 MediaSpecimen mediaSpecimen
= (MediaSpecimen
) specimen
;
1428 Iterator
<MediaRepresentation
> it
= mediaSpecimen
.getMediaSpecimen().getRepresentations().iterator();
1429 String mediaUris
= extractMediaUris(it
);
1430 csvLine
[table
.getIndex(CdmLightExportTable
.MEDIA_SPECIMEN_URL
)] = mediaUris
;
1434 if (specimen
.getDerivedFrom() != null){
1435 for (SpecimenOrObservationBase
<?
> original
: specimen
.getDerivedFrom().getOriginals()){
1436 //TODO: What to do if there are more then one FieldUnit??
1437 if (original
instanceof FieldUnit
){
1438 FieldUnit fieldUnit
= (FieldUnit
)original
;
1439 csvLine
[table
.getIndex(CdmLightExportTable
.COLLECTOR_NUMBER
)] = fieldUnit
.getFieldNumber();
1441 GatheringEvent gathering
= fieldUnit
.getGatheringEvent();
1442 if (gathering
!= null){
1443 if (gathering
.getLocality() != null){ csvLine
[table
.getIndex(CdmLightExportTable
.LOCALITY
)] = gathering
.getLocality().getText();}
1444 if (gathering
.getCountry() != null){csvLine
[table
.getIndex(CdmLightExportTable
.COUNTRY
)] = gathering
.getCountry().getLabel();}
1445 csvLine
[table
.getIndex(CdmLightExportTable
.COLLECTOR_STRING
)] = createCollectorString(state
, gathering
, fieldUnit
);
1446 addCollectingAreas(state
, gathering
);
1447 if (gathering
.getGatheringDate() != null){csvLine
[table
.getIndex(CdmLightExportTable
.COLLECTION_DATE
)] = gathering
.getGatheringDate().toString();}
1448 if (!gathering
.getCollectingAreas().isEmpty()){
1450 csvLine
[table
.getIndex(CdmLightExportTable
.FURTHER_AREAS
)] = "0";
1451 for (NamedArea area
: gathering
.getCollectingAreas()){
1453 csvLine
[table
.getIndex(CdmLightExportTable
.AREA_CATEGORY1
)] = area
.getTermType().getKey();
1454 csvLine
[table
.getIndex(CdmLightExportTable
.AREA_NAME1
)] = area
.getLabel();
1457 csvLine
[table
.getIndex(CdmLightExportTable
.AREA_CATEGORY2
)] = area
.getTermType().getKey();
1458 csvLine
[table
.getIndex(CdmLightExportTable
.AREA_NAME2
)] = area
.getLabel();
1461 csvLine
[table
.getIndex(CdmLightExportTable
.AREA_CATEGORY3
)] = area
.getTermType().getKey();
1462 csvLine
[table
.getIndex(CdmLightExportTable
.AREA_NAME3
)] = area
.getLabel();
1465 csvLine
[table
.getIndex(CdmLightExportTable
.FURTHER_AREAS
)] = "1";
1476 state
.getProcessor().put(table
, specimen
, csvLine
);
1477 } catch (Exception e
) {
1478 state
.getResult().addException(e
, "An unexpected error occurred when handling specimen " +
1479 cdmBaseStr(specimen
) + ": " + e
.getMessage());
1486 private String
extractMediaUris(Iterator
<MediaRepresentation
> it
) {
1487 String mediaUriString
= "";
1488 boolean first
= true;
1489 while(it
.hasNext()){
1490 MediaRepresentation rep
= it
.next();
1491 List
<MediaRepresentationPart
> parts
= rep
.getParts();
1492 for (MediaRepresentationPart part
: parts
){
1494 if (part
.getUri() != null){
1495 mediaUriString
+= part
.getUri().toString();
1499 if (part
.getUri() != null){
1500 mediaUriString
+= ", " +part
.getUri().toString();
1505 return mediaUriString
;
1512 private void addCollectingAreas(CdmLightExportState state
, GatheringEvent gathering
) {
1513 // TODO implement !!!
1515 if (!gathering
.getCollectingAreas().isEmpty()){
1516 state
.getResult().addWarning("Collecting areas not yet implemented but gathering " +
1517 cdmBaseStr(gathering
) + " has collecting areas.");
1526 private String
createCollectorString(CdmLightExportState state
, GatheringEvent gathering
, FieldUnit fieldUnit
) {
1528 String collectorString
= "";
1529 AgentBase
<?
> collectorA
= CdmBase
.deproxy(gathering
.getCollector());
1530 if (gathering
.getCollector() != null){
1531 if (collectorA
instanceof TeamOrPersonBase
1532 && state
.getConfig().isHighLightPrimaryCollector()){
1534 Person primaryCollector
= fieldUnit
.getPrimaryCollector();
1535 if (collectorA
instanceof Team
){
1536 Team collectorTeam
= (Team
)collectorA
;
1537 boolean isFirst
= true;
1538 for (Person member
: collectorTeam
.getTeamMembers()){
1540 collectorString
+= "; ";
1542 if (member
.equals(primaryCollector
)){
1544 collectorString
+= "<b>" + member
.getTitleCache() + "</b>";
1546 collectorString
+= member
.getTitleCache();
1551 collectorString
= collectorA
.getTitleCache();
1554 return collectorString
;
1555 } catch (Exception e
) {
1556 state
.getResult().addException(e
, "An unexpected error occurred when creating collector string for " +
1557 cdmBaseStr(fieldUnit
) + ": " + e
.getMessage());
1564 * Returns a string representation of the {@link CdmBase cdmBase} object
1565 * for result messages.
1567 private String
cdmBaseStr(CdmBase cdmBase
) {
1568 if (cdmBase
== null){
1569 return "-no object available-";
1571 return cdmBase
.getClass().getSimpleName() + ": " + cdmBase
.getUuid();
1579 protected boolean doCheck(CdmLightExportState state
) {
1587 protected boolean isIgnore(CdmLightExportState state
) {