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
.coldp
;
12 import java
.util
.ArrayList
;
13 import java
.util
.Collection
;
14 import java
.util
.Collections
;
15 import java
.util
.Comparator
;
16 import java
.util
.HashSet
;
17 import java
.util
.Iterator
;
18 import java
.util
.List
;
21 import java
.util
.UUID
;
23 import org
.apache
.commons
.lang3
.StringUtils
;
24 import org
.joda
.time
.DateTime
;
25 import org
.joda
.time
.DateTimeFieldType
;
26 import org
.joda
.time
.Partial
;
27 import org
.joda
.time
.format
.DateTimeFormatter
;
28 import org
.joda
.time
.format
.DateTimeFormatterBuilder
;
29 import org
.springframework
.stereotype
.Component
;
31 import eu
.etaxonomy
.cdm
.api
.service
.name
.TypeDesignationSetComparator
;
32 import eu
.etaxonomy
.cdm
.api
.service
.name
.TypeDesignationSetContainer
;
33 import eu
.etaxonomy
.cdm
.common
.CdmUtils
;
34 import eu
.etaxonomy
.cdm
.common
.URI
;
35 import eu
.etaxonomy
.cdm
.common
.monitor
.IProgressMonitor
;
36 import eu
.etaxonomy
.cdm
.filter
.TaxonNodeFilter
;
37 import eu
.etaxonomy
.cdm
.format
.reference
.OriginalSourceFormatter
;
38 import eu
.etaxonomy
.cdm
.hibernate
.HibernateProxyHelper
;
39 import eu
.etaxonomy
.cdm
.io
.cdmLight
.OrderHelper
;
40 import eu
.etaxonomy
.cdm
.io
.coldp
.ColDpExportTransformer
.ColDpNameRelType
;
41 import eu
.etaxonomy
.cdm
.io
.common
.CdmExportBase
;
42 import eu
.etaxonomy
.cdm
.io
.common
.ExportResult
.ExportResultState
;
43 import eu
.etaxonomy
.cdm
.io
.common
.TaxonNodeOutStreamPartitioner
;
44 import eu
.etaxonomy
.cdm
.io
.common
.XmlExportState
;
45 import eu
.etaxonomy
.cdm
.io
.common
.mapping
.out
.IExportTransformer
;
46 import eu
.etaxonomy
.cdm
.model
.agent
.AgentBase
;
47 import eu
.etaxonomy
.cdm
.model
.agent
.Person
;
48 import eu
.etaxonomy
.cdm
.model
.agent
.Team
;
49 import eu
.etaxonomy
.cdm
.model
.agent
.TeamOrPersonBase
;
50 import eu
.etaxonomy
.cdm
.model
.common
.AnnotatableEntity
;
51 import eu
.etaxonomy
.cdm
.model
.common
.Annotation
;
52 import eu
.etaxonomy
.cdm
.model
.common
.AnnotationType
;
53 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
54 import eu
.etaxonomy
.cdm
.model
.common
.ICdmBase
;
55 import eu
.etaxonomy
.cdm
.model
.common
.IIdentifiableEntity
;
56 import eu
.etaxonomy
.cdm
.model
.common
.IdentifiableEntity
;
57 import eu
.etaxonomy
.cdm
.model
.common
.IdentifiableSource
;
58 import eu
.etaxonomy
.cdm
.model
.common
.Identifier
;
59 import eu
.etaxonomy
.cdm
.model
.common
.Language
;
60 import eu
.etaxonomy
.cdm
.model
.common
.LanguageString
;
61 import eu
.etaxonomy
.cdm
.model
.common
.TimePeriod
;
62 import eu
.etaxonomy
.cdm
.model
.description
.CommonTaxonName
;
63 import eu
.etaxonomy
.cdm
.model
.description
.DescriptionBase
;
64 import eu
.etaxonomy
.cdm
.model
.description
.DescriptionElementBase
;
65 import eu
.etaxonomy
.cdm
.model
.description
.Distribution
;
66 import eu
.etaxonomy
.cdm
.model
.description
.Feature
;
67 import eu
.etaxonomy
.cdm
.model
.description
.TaxonDescription
;
68 import eu
.etaxonomy
.cdm
.model
.description
.TaxonInteraction
;
69 import eu
.etaxonomy
.cdm
.model
.description
.TextData
;
70 import eu
.etaxonomy
.cdm
.model
.location
.Country
;
71 import eu
.etaxonomy
.cdm
.model
.location
.NamedArea
;
72 import eu
.etaxonomy
.cdm
.model
.location
.Point
;
73 import eu
.etaxonomy
.cdm
.model
.media
.ExternalLink
;
74 import eu
.etaxonomy
.cdm
.model
.media
.Media
;
75 import eu
.etaxonomy
.cdm
.model
.media
.MediaRepresentation
;
76 import eu
.etaxonomy
.cdm
.model
.media
.MediaRepresentationPart
;
77 import eu
.etaxonomy
.cdm
.model
.name
.HomotypicalGroup
;
78 import eu
.etaxonomy
.cdm
.model
.name
.NameRelationship
;
79 import eu
.etaxonomy
.cdm
.model
.name
.NameRelationshipType
;
80 import eu
.etaxonomy
.cdm
.model
.name
.NameTypeDesignation
;
81 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalStatus
;
82 import eu
.etaxonomy
.cdm
.model
.name
.Rank
;
83 import eu
.etaxonomy
.cdm
.model
.name
.SpecimenTypeDesignation
;
84 import eu
.etaxonomy
.cdm
.model
.name
.TaxonName
;
85 import eu
.etaxonomy
.cdm
.model
.name
.TextualTypeDesignation
;
86 import eu
.etaxonomy
.cdm
.model
.name
.TypeDesignationBase
;
87 import eu
.etaxonomy
.cdm
.model
.occurrence
.DerivedUnit
;
88 import eu
.etaxonomy
.cdm
.model
.occurrence
.FieldUnit
;
89 import eu
.etaxonomy
.cdm
.model
.occurrence
.GatheringEvent
;
90 import eu
.etaxonomy
.cdm
.model
.reference
.IOriginalSource
;
91 import eu
.etaxonomy
.cdm
.model
.reference
.ISourceable
;
92 import eu
.etaxonomy
.cdm
.model
.reference
.Reference
;
93 import eu
.etaxonomy
.cdm
.model
.taxon
.Classification
;
94 import eu
.etaxonomy
.cdm
.model
.taxon
.Synonym
;
95 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
96 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
97 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonNode
;
98 import eu
.etaxonomy
.cdm
.model
.term
.IdentifierType
;
99 import eu
.etaxonomy
.cdm
.persistence
.dto
.TaxonNodeDto
;
100 import eu
.etaxonomy
.cdm
.persistence
.dto
.TaxonNodeDtoByRankAndNameComparator
;
101 import eu
.etaxonomy
.cdm
.strategy
.cache
.HTMLTagRules
;
102 import eu
.etaxonomy
.cdm
.strategy
.cache
.TagEnum
;
103 import eu
.etaxonomy
.cdm
.strategy
.cache
.TaggedText
;
106 * Classification or taxon tree exporter into COL-DP format.
111 public class ColDpClassificationExport
112 extends CdmExportBase
<ColDpExportConfigurator
,ColDpExportState
,IExportTransformer
,File
>{
114 private static final long serialVersionUID
= 4288364478648729869L;
116 public ColDpClassificationExport() {
117 this.ioName
= this.getClass().getSimpleName();
121 public long countSteps(ColDpExportState state
) {
122 TaxonNodeFilter filter
= state
.getConfig().getTaxonNodeFilter();
123 return getTaxonNodeService().count(filter
);
127 protected void doInvoke(ColDpExportState state
) {
130 IProgressMonitor monitor
= state
.getConfig().getProgressMonitor();
131 ColDpExportConfigurator config
= state
.getConfig();
134 if (config
.getTaxonNodeFilter().hasClassificationFilter()) {
135 Classification classification
= getClassificationService()
136 .load(config
.getTaxonNodeFilter().getClassificationFilter().get(0).getUuid());
137 state
.setRootId(classification
.getRootNode().getUuid());
138 } else if (config
.getTaxonNodeFilter().hasSubtreeFilter()) {
139 state
.setRootId(config
.getTaxonNodeFilter().getSubtreeFilter().get(0).getUuid());
142 @SuppressWarnings({ "unchecked", "rawtypes" })
143 TaxonNodeOutStreamPartitioner
<XmlExportState
> partitioner
= TaxonNodeOutStreamPartitioner
.NewInstance(this,
144 state
, state
.getConfig().getTaxonNodeFilter(), 100, monitor
, null);
146 // handleMetaData(state); //FIXME metadata;
147 monitor
.subTask("Start partitioning");
149 TaxonNode node
= partitioner
.next();
150 while (node
!= null) {
151 handleTaxonNode(state
, node
);
152 node
= partitioner
.next();
155 // get rootNode and create helperObjects
156 if (state
.getRootId() != null) {
157 List
<TaxonNodeDto
> childrenOfRoot
= state
.getNodeChildrenMap().get(state
.getRootId());
159 Comparator
<TaxonNodeDto
> comp
= state
.getConfig().getTaxonNodeComparator();
162 comp
= new TaxonNodeDtoByRankAndNameComparator();
164 if (childrenOfRoot
!= null) {
165 Collections
.sort(childrenOfRoot
, comp
);
166 OrderHelper helper
= new OrderHelper(state
.getRootId());
167 helper
.setOrderIndex(state
.getActualOrderIndexAndUpdate());
168 state
.getOrderHelperMap().put(state
.getRootId(), helper
);
170 for (TaxonNodeDto child
: childrenOfRoot
) {
171 OrderHelper childHelper
= new OrderHelper(child
.getTaxonUuid());
172 helper
.addChild(childHelper
);
173 childHelper
.setOrderIndex(state
.getActualOrderIndexAndUpdate());
174 childHelper
.addChildren(
175 createOrderHelper(state
.getNodeChildrenMap().get(child
.getUuid()), state
));
179 state
.getNodeChildrenMap().clear();
180 for (OrderHelper order
: state
.getOrderHelperMap().values()) {
181 setOrderIndex(state
, order
);
185 state
.getProcessor().createFinalResult(state
);
186 } catch (Exception e
) {
187 state
.getResult().addException(e
,
188 "An unexpected error occurred in main method doInvoke() " + e
.getMessage());
193 private void setOrderIndex(ColDpExportState state
, OrderHelper order
) {
195 if (order
.getTaxonUuid() != null
196 && state
.getProcessor().hasRecord(ColDpExportTable
.TAXON
, order
.getTaxonUuid().toString())) {
197 String
[] csvLine
= state
.getProcessor().getRecord(ColDpExportTable
.TAXON
,
198 order
.getTaxonUuid().toString());
199 csvLine
[ColDpExportTable
.TAXON
.getIndex(ColDpExportTable
.TAX_SEQ_INDEX
)] = String
200 .valueOf(order
.getOrderIndex());
203 if (order
.getChildren() == null) {
206 for (OrderHelper helper
: order
.getChildren()) {
207 setOrderIndex(state
, helper
);
211 private List
<OrderHelper
> createOrderHelper(List
<TaxonNodeDto
> nodes
, ColDpExportState state
) {
212 List
<TaxonNodeDto
> children
= nodes
;
213 // alreadySortedNodes.add(parentUuid);
214 if (children
== null) {
217 Comparator
<TaxonNodeDto
> comp
= state
.getConfig().getTaxonNodeComparator();
219 comp
= new TaxonNodeDtoByRankAndNameComparator();
221 Collections
.sort(children
, comp
);
222 // TODO 3 taxon ordering: nochmal checken!!! - s.auch seq index
223 OrderHelper helperChild
;
224 List
<OrderHelper
> childrenHelper
= new ArrayList
<>();
225 for (TaxonNodeDto child
: children
) {
226 helperChild
= new OrderHelper(child
.getTaxonUuid());
227 helperChild
.setOrderIndex(state
.getActualOrderIndexAndUpdate());
229 if (state
.getNodeChildrenMap().get(child
.getUuid()) != null) {
230 children
= state
.getNodeChildrenMap().get(child
.getUuid());
231 helperChild
.addChildren(createOrderHelper(children
, state
));
233 childrenHelper
.add(helperChild
);
235 return childrenHelper
;
238 private void handleTaxonNode(ColDpExportState state
, TaxonNode taxonNode
) {
240 if (taxonNode
== null) {
241 String message
= "TaxonNode for given taxon node UUID not found. ";
242 // TODO 3 taxon node not found
243 state
.getResult().addError(message
);
246 TaxonNode root
= taxonNode
;
247 List
<TaxonNodeDto
> childNodes
;
248 if (root
.hasChildNodes()) {
249 childNodes
= new ArrayList
<>();
250 for (TaxonNode child
: root
.getChildNodes()) {
252 childNodes
.add(new TaxonNodeDto(child
));
255 state
.getNodeChildrenMap().put(root
.getUuid(), childNodes
);
257 // add root to node map
259 TaxonNodeDto rootDto
= new TaxonNodeDto(root
);
260 UUID parentUuid
= root
.getParent() != null ? root
.getParent().getUuid()
261 : state
.getClassificationUUID(root
);
262 List
<TaxonNodeDto
> children
= state
.getNodeChildrenMap().get(parentUuid
);
263 if (children
!= null && !children
.contains(rootDto
)) {
264 state
.getNodeChildrenMap().get(parentUuid
).add(rootDto
);
265 } else if (state
.getNodeChildrenMap().get(parentUuid
) == null) {
266 List
<TaxonNodeDto
> rootList
= new ArrayList
<>();
267 rootList
.add(rootDto
);
268 state
.getNodeChildrenMap().put(parentUuid
, rootList
);
270 if (root
.hasTaxon()) {
271 handleTaxon(state
, root
);
273 } catch (Exception e
) {
274 state
.getResult().addException(e
, "An unexpected error occurred when handling taxonNode "
275 + taxonNode
.getUuid() + ": " + e
.getMessage() + e
.getStackTrace());
280 private void handleTaxon(ColDpExportState state
, TaxonNode taxonNode
) {
282 if (taxonNode
== null) {
283 state
.getResult().addError("The taxonNode was null.", "handleTaxon");
284 state
.getResult().setState(ExportResultState
.INCOMPLETE_WITH_ERROR
);
288 if (taxonNode
.getTaxon() == null) {
289 state
.getResult().addError("There was a taxon node without a taxon: " + taxonNode
.getUuid(),
291 state
.getResult().setState(ExportResultState
.INCOMPLETE_WITH_ERROR
);
298 Taxon taxon
= CdmBase
.deproxy(taxonNode
.getTaxon());
301 TaxonName name
= taxon
.getName();
302 handleName(state
, name
, taxon
, true);
304 if (state
.getConfig().isDoSynonyms()) {
305 //homotypic group / synonyms
306 HomotypicalGroup homotypicGroup
= taxon
.getHomotypicGroup();
308 handleHomotypicalGroup(state
, homotypicGroup
, taxon
);
309 for (Synonym syn
: taxon
.getSynonymsInGroup(homotypicGroup
)) {
310 handleSynonym(state
, syn
, index
);
314 List
<HomotypicalGroup
> heterotypicHomotypicGroups
= taxon
.getHeterotypicSynonymyGroups();
315 for (HomotypicalGroup group
: heterotypicHomotypicGroups
){
316 handleHomotypicalGroup(state
, group
, taxon
);
317 for (Synonym syn
: taxon
.getSynonymsInGroup(group
)) {
318 handleSynonym(state
, syn
, index
);
324 //TODO 2 pro parte synonyms and misapplications
325 // //pro parte synonyms
327 // for (Taxon tax : taxon.getAllProParteSynonyms()) {
328 // handleProPartePartialMisapplied(state, tax, taxon, true, false, index);
333 // for (Taxon tax : taxon.getAllMisappliedNames()) {
334 // handleProPartePartialMisapplied(state, tax, taxon, false, true, index);
339 ColDpExportTable table
= ColDpExportTable
.TAXON
;
340 String
[] csvLine
= new String
[table
.getSize()];
342 csvLine
[table
.getIndex(ColDpExportTable
.ID
)] = getId(state
, taxon
);
345 handleAlternativeId(state
, csvLine
, table
, taxon
);
347 //TODO 9 sourceID //handled in referenceID
348 csvLine
[table
.getIndex(ColDpExportTable
.SOURCE_ID
)] = null;
350 Taxon parent
= (taxonNode
.getParent() == null) ?
null : taxonNode
.getParent().getTaxon();
351 csvLine
[table
.getIndex(ColDpExportTable
.TAX_PARENT_ID
)] = getId(state
, parent
);
355 //TODO 9 branchLength
356 csvLine
[table
.getIndex(ColDpExportTable
.TAX_BRANCH_LENGTH
)] = null;
359 csvLine
[table
.getIndex(ColDpExportTable
.TAX_NAME_ID
)] = getId(state
, name
);
362 csvLine
[table
.getIndex(ColDpExportTable
.TAX_NAMEPHRASE
)] = taxon
.getAppendedPhrase();
365 csvLine
[table
.getIndex(ColDpExportTable
.TAX_SEC_ID
)] = getId(state
, taxon
.getSec());
366 if (taxon
.getSec() != null
367 && (!state
.getReferenceStore().contains((taxon
.getSec().getUuid())))) {
368 handleReference(state
, taxon
.getSec());
372 //TODO 4 SCRUTINIZER ID
373 //TODO 4 SCRUTINIZER Date
375 //TODO 2 taxon provisional, still an open issue?
376 csvLine
[table
.getIndex(ColDpExportTable
.TAX_PROVISIONAL
)] = taxonNode
.isDoubtful() ?
"1" : "0";
379 handleReference(state
, csvLine
, table
, taxon
);
381 //TODO 3 taxon extinct
383 //TODO 7 taxon temporalRangeStart
384 csvLine
[table
.getIndex(ColDpExportTable
.TAX_TEMPORAL_RANGE_END
)] = null;
385 //TODO 7 taxon temporalRangeEnd
386 csvLine
[table
.getIndex(ColDpExportTable
.TAX_TEMPORAL_RANGE_END
)] = null;
388 //TODO 5 taxon environment
389 csvLine
[table
.getIndex(ColDpExportTable
.TAX_ENVIRONMENT
)] = null;
391 //TODO 6 taxon species, section, subgenus, genus, ... - can be null if parent ID is given
394 csvLine
[table
.getIndex(ColDpExportTable
.REMARKS
)] = getRemarks(taxon
);
396 //TODO 1 taxon only published
399 state
.getProcessor().put(table
, taxon
, csvLine
);
402 handleDescriptions(state
, taxon
);
405 handleMedia(state
, taxon
);
407 } catch (Exception e
) {
409 state
.getResult().addException(e
,
410 "An unexpected problem occurred when trying to export taxon with id " + taxon
.getId() + " " + taxon
.getTitleCache());
411 state
.getResult().setState(ExportResultState
.INCOMPLETE_WITH_ERROR
);
413 } catch (Exception e
) {
414 state
.getResult().addException(e
, "An unexpected error occurred when handling the taxon node of "
415 + cdmBaseStr(taxonNode
.getTaxon()) + ", titleCache:"+ taxonNode
.getTaxon().getTitleCache()+": " + e
.getMessage());
419 private void handleAlternativeId(ColDpExportState state
, String
[] csvLine
, ColDpExportTable table
, IdentifiableEntity
<?
> entity
) {
420 String alternativeIdStr
= null;
422 for (Identifier identifier
: entity
.getIdentifiers()) {
423 //TODO 4 alternativeID filter Identifiers
424 IdentifierType type
= identifier
.getType();
425 String prefix
= null;
426 String value
= identifier
.getIdentifier();
427 String url
= identifier
.getUrl();
429 //TODO 4 alternativeID handle other identifier types
430 if (type
.equals(IdentifierType
.IDENTIFIER_NAME_WFO())) {
432 value
= value
.replace("wfo-", "");
434 }else if (url
!= null && !url
.isEmpty() && isUrl(url
)) {
437 //TODO 4 alternativeID log failing identifier
439 alternativeIdStr
= CdmUtils
.concat(",", alternativeIdStr
, CdmUtils
.concat(":", prefix
, value
));
442 csvLine
[table
.getIndex(ColDpExportTable
.ALTERNATIVE_ID
)] = alternativeIdStr
;
445 private boolean isUrl(String url
) {
447 if (url
.startsWith("http")) {
451 } catch (Exception e
) {
452 //exception should return false
457 private void handleMedia(ColDpExportState state
, Taxon taxon
) {
458 Set
<Media
> mediaSet
= new HashSet
<>();
460 //TODO 3 media collect media form other places
462 //collect from taxon image gallery
463 Set
<?
extends DescriptionBase
<?
>> descriptions
= taxon
.getDescriptions();
464 for (DescriptionBase
<?
> description
: descriptions
){
465 for (DescriptionElementBase o
: description
.getElements()){
466 DescriptionElementBase el
= CdmBase
.deproxy(o
);
467 if (el
.getMedia().size() > 0){
468 for (Media media
: el
.getMedia()){
475 //handle single media
476 for (Media media
: mediaSet
) {
477 for (MediaRepresentation repr
: media
.getRepresentations()){
478 for (MediaRepresentationPart part
: repr
.getParts()){
479 handleMediaRepresentation(state
, taxon
, part
);
485 private void handleMediaRepresentation(ColDpExportState state
, Taxon taxon
, MediaRepresentationPart part
) {
486 if (part
== null || state
.getMediaStore().contains(part
.getUuid())) {
490 state
.addMediaToStore(part
);
491 ColDpExportTable table
= ColDpExportTable
.MEDIA
;
492 String
[] csvLine
= new String
[table
.getSize()];
493 part
= HibernateProxyHelper
.deproxy(part
);
495 csvLine
[table
.getIndex(ColDpExportTable
.TAXON_ID
)] = getId(state
, taxon
);
497 //TODO 9 media sourceID //handled in referenceID
498 csvLine
[table
.getIndex(ColDpExportTable
.SOURCE_ID
)] = null;
501 if (part
.getUri() != null) {
502 csvLine
[table
.getIndex(ColDpExportTable
.MEDIA_URL
)] = part
.getUri().toString();
505 //TODO 3 media type, still open?
506 csvLine
[table
.getIndex(ColDpExportTable
.TYPE
)] = part
.getMediaRepresentation().getMimeType();
508 //TODO 3 media format
509 csvLine
[table
.getIndex(ColDpExportTable
.MEDIA_FORMAT
)] = null;
511 Media media
= part
.getMediaRepresentation().getMedia();
514 csvLine
[table
.getIndex(ColDpExportTable
.MEDIA_TITLE
)] = getTitleCache(media
);
517 csvLine
[table
.getIndex(ColDpExportTable
.MEDIA_CREATED
)] = toIsoDate(media
.getMediaCreated());
519 //creator //TODO 3 media format creator
520 csvLine
[table
.getIndex(ColDpExportTable
.MEDIA_CREATOR
)] = getTitleCache(media
.getArtist());
522 //TODO 5 media license
523 csvLine
[table
.getIndex(ColDpExportTable
.MEDIA_LICENSE
)] = null;
526 csvLine
[table
.getIndex(ColDpExportTable
.LINK
)] = null;
528 state
.getProcessor().put(table
, part
, csvLine
);
531 private String
toIsoDate(TimePeriod mediaCreated
) {
532 if (mediaCreated
== null) {
535 //TODO 2 date, what if end or freetext exist?
536 Partial partial
= mediaCreated
.getStart();
537 if (partial
== null || !partial
.isSupported(DateTimeFieldType
.year())
538 || !partial
.isSupported(DateTimeFieldType
.monthOfYear()) && partial
.isSupported(DateTimeFieldType
.dayOfMonth())) {
539 //TODO 2 date, log warning, also if mediaCreated.getEnd() != null or so
542 DateTimeFormatter formatter
= new DateTimeFormatterBuilder()
543 .appendYear(4, 4).appendLiteral('-')
544 .appendMonthOfYear(2).appendLiteral('-')
547 return partial
.toString(formatter
);
552 * transforms the given date to an iso date
554 protected String
toIsoDate(DateTime dateTime
) {
555 if (dateTime
== null) {
558 DateTimeFormatter formatter
= new DateTimeFormatterBuilder()
559 .appendYear(4, 4).appendLiteral('-')
560 .appendMonthOfYear(2).appendLiteral('-')
563 return formatter
.print(dateTime
);
566 private void handleDescriptions(ColDpExportState state
, Taxon taxon
) {
567 if (!state
.getConfig().isDoFactualData()) {
570 String titleCache
= null;
572 taxon
= HibernateProxyHelper
.deproxy(taxon
);
573 titleCache
= taxon
.getTitleCache();
574 Set
<TaxonDescription
> descriptions
= taxon
.getDescriptions();
575 List
<DescriptionElementBase
> distributionFacts
= new ArrayList
<>();
576 List
<DescriptionElementBase
> taxonInteractionsFacts
= new ArrayList
<>();
577 List
<DescriptionElementBase
> commonNameFacts
= new ArrayList
<>();
578 for (TaxonDescription description
: descriptions
) {
579 if (description
.getElements() != null &&
580 description
.isPublish() || state
.getConfig().isIncludeUnpublishedFacts()){
581 for (DescriptionElementBase element
: description
.getElements()) {
582 element
= CdmBase
.deproxy(element
);
583 if (element
.getFeature().equals(Feature
.COMMON_NAME())) {
584 commonNameFacts
.add(element
);
585 } else if (element
.getFeature().equals(Feature
.DISTRIBUTION())) {
586 distributionFacts
.add(element
);
587 } else if (element
.getFeature().isSupportsTaxonInteraction()) {
588 taxonInteractionsFacts
.add(element
);
595 if (!commonNameFacts
.isEmpty()) {
596 handleCommonNameFacts(state
, taxon
, commonNameFacts
);
598 if (!distributionFacts
.isEmpty()) {
599 handleDistributionFacts(state
, taxon
, distributionFacts
);
601 if (!taxonInteractionsFacts
.isEmpty()) {
602 handleTaxonInteractionsFacts(state
, taxon
, taxonInteractionsFacts
);
604 } catch (Exception e
) {
605 state
.getResult().addException(e
, "An unexpected error occurred when handling description of "
606 + cdmBaseStr(taxon
) + (titleCache
!= null?
(" " +titleCache
) : "")+": " + e
.getMessage());
610 private String
getRemarks(AnnotatableEntity entity
) {
611 String remarks
= null;
612 for (Annotation a
: entity
.getAnnotations()) {
613 //TODO 3 handle other annotation types
614 if (AnnotationType
.EDITORIAL().equals(a
.getAnnotationType())
615 && CdmUtils
.isNotBlank(a
.getText())){
616 remarks
= CdmUtils
.concat(";", remarks
, a
.getText());
622 // private void handleMetaData(ColDpExportState state) {
623 // ColDpExportTable table = ColDpExportTable.METADATA;
624 // String[] csvLine = new String[table.getSize()];
625 //// csvLine[table.getIndex(CdmLightExportTable.INSTANCE_ID)] = state.getConfig().getInctanceId();
626 //// csvLine[table.getIndex(CdmLightExportTable.INSTANCE_NAME)] = state.getConfig().getInstanceName();
627 // csvLine[table.getIndex(ColDpExportTable.DATASET_BASE_URL)] = state.getConfig().getBase_url();
628 // csvLine[table.getIndex(ColDpExportTable.DATASET_CONTRIBUTOR)] = state.getConfig().getContributor();
629 // csvLine[table.getIndex(ColDpExportTable.DATASET_CREATOR)] = state.getConfig().getCreator();
630 // csvLine[table.getIndex(ColDpExportTable.DATASET_DESCRIPTION)] = state.getConfig().getDescription();
631 // csvLine[table.getIndex(ColDpExportTable.DATASET_DOWNLOAD_LINK)] = state.getConfig().getDataset_download_link();
632 // csvLine[table.getIndex(ColDpExportTable.DATASET_KEYWORDS)] = state.getConfig().getKeywords();
633 // csvLine[table.getIndex(ColDpExportTable.DATASET_LANDINGPAGE)] = state.getConfig().getDataSet_landing_page();
635 // csvLine[table.getIndex(ColDpExportTable.DATASET_LANGUAGE)] = state.getConfig().getLanguage() != null? state.getConfig().getLanguage().getLabel(): null;
636 // csvLine[table.getIndex(ColDpExportTable.DATASET_LICENCE)] = state.getConfig().getLicence();
637 // csvLine[table.getIndex(ColDpExportTable.DATASET_LOCATION)] = state.getConfig().getLocation();
638 // csvLine[table.getIndex(ColDpExportTable.DATASET_RECOMMENDED_CITATTION)] = state.getConfig().getRecommended_citation();
639 // csvLine[table.getIndex(ColDpExportTable.DATASET_TITLE)] = state.getConfig().getTitle();
640 // state.getProcessor().put(table, "", csvLine);
643 private void handleTaxonInteractionsFacts(ColDpExportState state
, CdmBase cdmBase
,
644 List
<DescriptionElementBase
> taxonInteractionsFacts
) {
646 ColDpExportTable table
= ColDpExportTable
.SPECIES_INTERACTION
;
647 String titleCache
= null;
648 if (cdmBase
instanceof TaxonBase
){
649 titleCache
= ((TaxonBase
)cdmBase
).getTitleCache();
651 for (DescriptionElementBase element
: taxonInteractionsFacts
) {
655 String
[] csvLine
= new String
[table
.getSize()];
657 // csvLine[table.getIndex(ColDpExportTable.TAXON_ID)] = getId(state, element);
658 handleSource(state
, element
, table
);
659 csvLine
[table
.getIndex(ColDpExportTable
.TAXON_ID
)] = getId(state
, cdmBase
);
660 csvLine
[table
.getIndex(ColDpExportTable
.REL_TAXON_TAXON_ID
)] = getId(state
,
661 ((TaxonInteraction
) element
).getTaxon2());
662 //TODO 5 taxon interaction Scentific name for species interaction
663 //TODO 2 taxon interaction, why does this handling from other remarks handling?
664 csvLine
[table
.getIndex(ColDpExportTable
.REMARKS
)] = createMultilanguageString(
665 ((TaxonInteraction
) element
).getDescription());
666 state
.getProcessor().put(table
, element
, csvLine
);
668 } catch (Exception e
) {
669 state
.getResult().addException(e
, "An unexpected error occurred when handling taxon interaction"
670 + cdmBaseStr(element
) + (titleCache
!= null?
(" " +titleCache
) : "")+ ": " + e
.getMessage());
675 private void handleSimpleMediaFact(ColDpExportState state
, Taxon taxon
, ColDpExportTable table
,
676 DescriptionElementBase element
) {
679 handleSource(state
, element
, ColDpExportTable
.MEDIA
);
681 if (element
instanceof TextData
) {
682 TextData textData
= (TextData
) element
;
683 csvLine
= new String
[table
.getSize()];
684 csvLine
[table
.getIndex(ColDpExportTable
.TAXON_ID
)] = getId(state
, taxon
);
686 String mediaUris
= "";
687 for (Media media
: textData
.getMedia()) {
688 String mediaString
= extractMediaUris(media
.getRepresentations().iterator());
689 if (!StringUtils
.isBlank(mediaString
)) {
690 mediaUris
+= mediaString
+ ";";
692 state
.getResult().addWarning("Empty Media object for " + taxon
.getUserFriendlyTypeName() + " "
693 + taxon
.getUuid() + " (media: " + media
.getUuid() + ")");
696 csvLine
[table
.getIndex(ColDpExportTable
.MEDIA_URL
)] = mediaUris
;
697 //TODO 2 media title, type (MIME-type), what is meant here?
698 csvLine
[table
.getIndex(ColDpExportTable
.MEDIA_TITLE
)] = mediaUris
;
700 } catch (Exception e
) {
701 state
.getResult().addException(e
, "An unexpected error occurred when handling single simple fact "
702 + cdmBaseStr(element
) + ": " + e
.getMessage());
707 private String
createMultilanguageString(Map
<Language
, LanguageString
> multilanguageText
) {
709 int index
= multilanguageText
.size();
710 for (LanguageString langString
: multilanguageText
.values()) {
711 text
+= langString
.getText();
720 private String
createAnnotationsString(Set
<Annotation
> annotations
) {
721 StringBuffer strBuff
= new StringBuffer();
723 for (Annotation ann
: annotations
) {
724 if (ann
.getAnnotationType() == null || !ann
.getAnnotationType().equals(AnnotationType
.TECHNICAL())) {
725 strBuff
.append(ann
.getText());
726 strBuff
.append("; ");
730 if (strBuff
.length() > 2) {
731 return strBuff
.substring(0, strBuff
.length() - 2);
737 private void handleSource(ColDpExportState state
, DescriptionElementBase element
,
738 ColDpExportTable factsTable
) {
739 // ColDpExportTable table = ColDpExportTable.FACT_SOURCES;
741 // Set<DescriptionElementSource> sources = element.getSources();
743 // for (DescriptionElementSource source : sources) {
744 // if (!(source.getType().equals(OriginalSourceType.Import)
745 // && state.getConfig().isExcludeImportSources())) {
746 // String[] csvLine = new String[table.getSize()];
747 // Reference ref = source.getCitation();
748 // if ((ref == null) && (source.getNameUsedInSource() == null)) {
751 // if (ref != null) {
752 // if (!state.getReferenceStore().contains(ref.getUuid())) {
753 // handleReference(state, ref);
756 // csvLine[table.getIndex(ColDpExportTable.REFERENCE_FK)] = getId(state, ref);
758 // csvLine[table.getIndex(ColDpExportTable.FACT_FK)] = getId(state, element);
760 // csvLine[table.getIndex(ColDpExportTable.NAME_IN_SOURCE_FK)] = getId(state,
761 // source.getNameUsedInSource());
762 // csvLine[table.getIndex(ColDpExportTable.FACT_TYPE)] = factsTable.getTableName();
763 // if (StringUtils.isBlank(csvLine[table.getIndex(ColDpExportTable.REFERENCE_FK)])
764 // && StringUtils.isBlank(csvLine[table.getIndex(ColDpExportTable.NAME_IN_SOURCE_FK)])) {
767 // state.getProcessor().put(table, source, csvLine);
770 // } catch (Exception e) {
771 // state.getResult().addException(e, "An unexpected error occurred when handling single source "
772 // + cdmBaseStr(element) + ": " + e.getMessage());
776 private void handleDistributionFacts(ColDpExportState state
, Taxon taxon
,
777 List
<DescriptionElementBase
> distributionFacts
) {
779 ColDpExportTable table
= ColDpExportTable
.DISTRIBUTION
;
780 Set
<Distribution
> distributions
= new HashSet
<>();
781 for (DescriptionElementBase element
: distributionFacts
) {
783 //TODO 3 distribution also check feature
784 if (element
instanceof Distribution
) {
785 String
[] csvLine
= new String
[table
.getSize()];
786 Distribution distribution
= (Distribution
) element
;
787 distributions
.add(distribution
);
789 csvLine
[table
.getIndex(ColDpExportTable
.TAXON_ID
)] = getId(state
, taxon
);
791 NamedArea area
= CdmBase
.deproxy(distribution
.getArea());
793 String gazetteer
= "text";
794 String areaID
= null;
795 if (area
.getClass().equals(Country
.class)) {
796 Country country
= CdmBase
.deproxy(area
, Country
.class);
797 areaID
= country
.getIdInVocabulary();
799 } else if (NamedArea
.isTdwgArea(area
)) {
801 areaID
= area
.getIdInVocabulary();
805 csvLine
[table
.getIndex(ColDpExportTable
.DIST_AREA_ID
)] = areaID
;
808 //TODO 3 distribution area, does this always use the full English? Looks like this is not true for countries.
809 csvLine
[table
.getIndex(ColDpExportTable
.DIST_AREA
)] = area
.getLabel();
812 csvLine
[table
.getIndex(ColDpExportTable
.DIST_GAZETTEER
)] = gazetteer
;
815 if (distribution
.getStatus() != null) {
816 csvLine
[table
.getIndex(ColDpExportTable
.DIST_STATUS
)]
817 = state
.getTransformer().getCacheByPresenceAbsenceTerm(distribution
.getStatus());
821 handleReference(state
, csvLine
, table
, distribution
);
824 csvLine
[table
.getIndex(ColDpExportTable
.REMARKS
)] = getRemarks(distribution
);
826 state
.getProcessor().put(table
, distribution
, csvLine
);
829 .addError("The distribution description for the taxon " + taxon
.getUuid()
830 + " is not of type distribution. Could not be exported. UUID of the description element: "
831 + element
.getUuid());
833 } catch (Exception e
) {
835 state
.getResult().addException(e
, "An unexpected error occurred when handling single distribution "
836 + cdmBaseStr(element
) + ": " + e
.getMessage());
841 private void handleCommonNameFacts(ColDpExportState state
, Taxon taxon
,
842 List
<DescriptionElementBase
> commonNameFacts
) {
843 ColDpExportTable table
= ColDpExportTable
.VERNACULAR_NAME
;
845 for (DescriptionElementBase element
: commonNameFacts
) {
847 if (element
instanceof CommonTaxonName
) {
848 String
[] csvLine
= new String
[table
.getSize()];
849 CommonTaxonName commonName
= (CommonTaxonName
) element
;
850 csvLine
[table
.getIndex(ColDpExportTable
.TAXON_ID
)] = getId(state
, taxon
);
851 if (commonName
.getName() != null) {
852 csvLine
[table
.getIndex(ColDpExportTable
.VERN_NAME
)] = commonName
.getName();
855 //transliteration - we do not have this yet
856 csvLine
[table
.getIndex(ColDpExportTable
.VERN_TRANSLITERATION
)] = commonName
.getTransliteration();
858 if (commonName
.getLanguage() != null) {
859 //TODO 2 common name char(3) lang
860 csvLine
[table
.getIndex(ColDpExportTable
.VERN_LANGUAGE
)] = commonName
.getLanguage().getIso639_2();
863 //TODO 2 common name country
865 if (commonName
.getArea() != null) {
866 csvLine
[table
.getIndex(ColDpExportTable
.VERN_AREA
)] = commonName
.getArea().getLabel();
869 //sex - we do not have this yet
870 csvLine
[table
.getIndex(ColDpExportTable
.VERN_SEX
)] = null;
873 handleReference(state
, csvLine
, table
, commonName
);
875 state
.getProcessor().put(table
, commonName
, csvLine
);
876 } else if (element
instanceof TextData
){
877 String
[] csvLine
= new String
[table
.getSize()];
878 TextData commonName
= (TextData
) element
;
879 handleSource(state
, element
, table
);
880 csvLine
[table
.getIndex(ColDpExportTable
.TAXON_ID
)] = getId(state
, taxon
);
881 if (commonName
.getMultilanguageText() != null) {
882 csvLine
[table
.getIndex(ColDpExportTable
.VERN_NAME
)] = createMultilanguageString(commonName
.getMultilanguageText());
884 state
.getProcessor().put(table
, commonName
, csvLine
);
887 .addError("The common name description for the taxon " + taxon
.getUuid()
888 + " is not of type common name. Could not be exported. UUID of the description element: "
889 + element
.getUuid());
891 } catch (Exception e
) {
892 state
.getResult().addException(e
, "An unexpected error occurred when handling single common name "
893 + cdmBaseStr(element
) + " - "+taxon
.getTitleCache()+ ": " + e
.getMessage());
898 private String
getTitleCache(IIdentifiableEntity identEntity
) {
899 if (identEntity
== null) {
902 // TODO 3 titleCache refresh?
903 return identEntity
.getTitleCache();
906 private String
getId(ColDpExportState state
, ICdmBase cdmBase
) {
907 if (cdmBase
== null) {
910 // TODO 4 id type, make configurable
911 return cdmBase
.getUuid().toString();
914 private void handleSynonym(ColDpExportState state
, Synonym synonym
, int index
) {
916 if (isUnpublished(state
.getConfig(), synonym
)) {
919 TaxonName name
= synonym
.getName();
920 handleName(state
, name
, synonym
.getAcceptedTaxon());
922 ColDpExportTable table
= ColDpExportTable
.SYNONYM
;
923 String
[] csvLine
= new String
[table
.getSize()];
925 csvLine
[table
.getIndex(ColDpExportTable
.ID
)] = getId(state
, synonym
);
927 //TODO 9 synonym sourceID //handled in referenceID and sec_ID
928 csvLine
[table
.getIndex(ColDpExportTable
.SOURCE_ID
)] = null;
930 csvLine
[table
.getIndex(ColDpExportTable
.TAXON_ID
)] = getId(state
, synonym
.getAcceptedTaxon());
931 csvLine
[table
.getIndex(ColDpExportTable
.TAX_NAME_ID
)] = getId(state
, name
);
932 if (synonym
.getSec() != null && !state
.getReferenceStore().contains(synonym
.getSec().getUuid())) {
933 handleReference(state
, synonym
.getSec());
934 csvLine
[table
.getIndex(ColDpExportTable
.REFERENCE_ID
)] = getId(state
, synonym
.getSec());
936 csvLine
[table
.getIndex(ColDpExportTable
.TAX_NAMEPHRASE
)] = synonym
.getAppendedPhrase();
937 csvLine
[table
.getIndex(ColDpExportTable
.TAX_SEC_ID
)] = getId(state
, synonym
.getSec());
939 state
.getProcessor().put(table
, synonym
, csvLine
);
940 } catch (Exception e
) {
941 state
.getResult().addException(e
, "An unexpected error occurred when handling synonym "
942 + cdmBaseStr(synonym
) + ": " + e
.getMessage());
947 // * Handles misapplied names (including pro parte and partial as well as pro
948 // * parte and partial synonyms
950 // private void handleProPartePartialMisapplied(ColDpExportState state, Taxon taxon, Taxon accepted, boolean isProParte, boolean isMisapplied, int index) {
952 // Taxon ppSyonym = taxon;
953 // if (isUnpublished(state.getConfig(), ppSyonym)) {
956 // TaxonName name = ppSyonym.getName();
957 // handleName(state, name, accepted);
959 // ColDpExportTable table = ColDpExportTable.SYNONYM;
960 // String[] csvLine = new String[table.getSize()];
962 // csvLine[table.getIndex(ColDpExportTable.SYNONYM_ID)] = getId(state, ppSyonym);
963 // csvLine[table.getIndex(ColDpExportTable.TAXON_FK)] = getId(state, accepted);
964 // csvLine[table.getIndex(ColDpExportTable.NAME_FK)] = getId(state, name);
966 // Reference secRef = ppSyonym.getSec();
968 // if (secRef != null && !state.getReferenceStore().contains(secRef.getUuid())) {
969 // handleReference(state, secRef);
971 // csvLine[table.getIndex(ColDpExportTable.SEC_REFERENCE_FK)] = getId(state, secRef);
972 // csvLine[table.getIndex(ColDpExportTable.SEC_REFERENCE)] = getTitleCache(secRef);
973 // Set<TaxonRelationship> rels = accepted.getTaxonRelations(ppSyonym);
974 // TaxonRelationship rel = null;
975 // boolean isPartial = false;
976 // if (rels.size() == 1){
977 // rel = rels.iterator().next();
979 // }else if (rels.size() > 1){
980 // Iterator<TaxonRelationship> iterator = rels.iterator();
981 // while (iterator.hasNext()){
982 // rel = iterator.next();
983 // if (isProParte && rel.getType().isAnySynonym()){
985 // } else if (isMisapplied && rel.getType().isAnyMisappliedName()){
993 // Reference synSecRef = rel.getCitation();
994 // if (synSecRef != null && !state.getReferenceStore().contains(synSecRef.getUuid())) {
995 // handleReference(state, synSecRef);
997 // csvLine[table.getIndex(ColDpExportTable.SYN_SEC_REFERENCE_FK)] = getId(state, synSecRef);
998 // csvLine[table.getIndex(ColDpExportTable.SYN_SEC_REFERENCE)] = getTitleCache(synSecRef);
999 // isProParte = rel.getType().isProParte();
1000 // isPartial = rel.getType().isPartial();
1003 // state.getResult().addWarning("An unexpected error occurred when handling "
1004 // + "pro parte/partial synonym or misapplied name " + cdmBaseStr(taxon) );
1007 // // pro parte type
1009 // csvLine[table.getIndex(ColDpExportTable.IS_PRO_PARTE)] = isProParte ? "1" : "0";
1010 // csvLine[table.getIndex(ColDpExportTable.IS_PARTIAL)] = isPartial ? "1" : "0";
1011 // csvLine[table.getIndex(ColDpExportTable.IS_MISAPPLIED)] = isMisapplied ? "1" : "0";
1012 // csvLine[table.getIndex(ColDpExportTable.SORT_INDEX)] = String.valueOf(index);
1013 // state.getProcessor().put(table, ppSyonym, csvLine);
1014 // } catch (Exception e) {
1015 // state.getResult().addException(e, "An unexpected error occurred when handling "
1016 // + "pro parte/partial synonym or misapplied name " + cdmBaseStr(taxon) + ": " + e.getMessage());
1020 private void handleName(ColDpExportState state
, TaxonName name
, Taxon acceptedTaxon
){
1021 handleName(state
, name
, acceptedTaxon
, false);
1024 private void handleName(ColDpExportState state
, TaxonName name
, Taxon acceptedTaxon
, boolean acceptedName
) {
1025 if (name
== null || state
.getNameStore().containsKey(name
.getId())) {
1029 //TODO is there a better way to handle configurable columns? #10451
1030 ColDpExportTable table
= state
.getConfig().isIncludeFullName() ? ColDpExportTable
.NAME_WITH_FULLNAME
:
1031 ColDpExportTable
.NAME
;
1033 String
[] csvLine
= new String
[table
.getSize()];
1035 Rank rank
= name
.getRank();
1036 name
= HibernateProxyHelper
.deproxy(name
);
1037 state
.getNameStore().put(name
.getId(), name
.getUuid());
1039 csvLine
[table
.getIndex(ColDpExportTable
.ID
)] = getId(state
, name
);
1041 //TODO 3 name, handle LSIDs
1042 // if (name.getLsid() != null) {
1043 // csvLine[table.getIndex(ColDpExportTable.LSID)] = name.getLsid().getLsid();
1045 // csvLine[table.getIndex(ColDpExportTable.LSID)] = "";
1047 handleAlternativeId(state
, csvLine
, table
, name
);
1049 //TODO 9 name sourceID
1050 csvLine
[table
.getIndex(ColDpExportTable
.SOURCE_ID
)] = null;
1053 TaxonName basionym
= name
.getBasionym(); //TODO 5 basionym, order in case there are >1 basionyms
1054 if (basionym
!= null) {
1055 if (!state
.getNameStore().containsKey(basionym
.getId())) {
1056 handleName(state
, basionym
, null);
1058 csvLine
[table
.getIndex(ColDpExportTable
.NAME_BASIONYM_ID
)] = getId(state
, basionym
);
1062 if (name
.isProtectedTitleCache() && StringUtils
.isEmpty(name
.getNameCache())) {
1063 //TODO 7 make it configurable if we should always take titleCache if titleCache is protected, as nameCache may not necessarily have complete data if titleCache is protected as it is considered to be irrelevant or at least preliminary
1064 String message
= "";
1065 if (StringUtils
.isEmpty(name
.getNameCache())) {
1066 csvLine
[table
.getIndex(ColDpExportTable
.NAME_SCIENTIFIC_NAME
)] = name
.getNameCache();
1067 message
= "ScientificName: Name cache " + name
.getNameCache() + " used for name with protected titleCache " + name
.getTitleCache();
1069 csvLine
[table
.getIndex(ColDpExportTable
.NAME_SCIENTIFIC_NAME
)] = name
.getTitleCache();
1070 message
= "ScientificName: Name has protected titleCache and no explicit nameCache: " + name
.getTitleCache();
1072 state
.getResult().addWarning(message
); //TODO 7 add location to warning
1074 csvLine
[table
.getIndex(ColDpExportTable
.NAME_SCIENTIFIC_NAME
)] = name
.getNameCache();
1076 if (state
.getConfig().isIncludeFullName()) {
1077 csvLine
[table
.getIndex(ColDpExportTable
.NAME_FULLNAME
)] = name
.getTitleCache();
1081 csvLine
[table
.getIndex(ColDpExportTable
.NAME_AUTHORSHIP
)] = name
.getAuthorshipCache();
1082 //combinationAuthorship
1083 csvLine
[table
.getIndex(ColDpExportTable
.NAME_COMBINATION_AUTHORSHIP
)] = teamToString(name
.getCombinationAuthorship());
1084 //combinationExAuthorship
1085 csvLine
[table
.getIndex(ColDpExportTable
.NAME_COMBINATION_EX_AUTHORSHIP
)] = teamToString(name
.getExCombinationAuthorship());
1086 //combinationAuthorshipYear
1087 csvLine
[table
.getIndex(ColDpExportTable
.NAME_COMBINATION_AUTHORSHIP_YEAR
)] = name
.getNomenclaturalReference() == null ?
null : name
.getNomenclaturalReference().getYear();
1088 //basionymAuthorship
1089 csvLine
[table
.getIndex(ColDpExportTable
.NAME_BASIONYM_AUTHORSHIP
)] = teamToString(name
.getBasionymAuthorship());
1090 //basionymExAuthorship
1091 csvLine
[table
.getIndex(ColDpExportTable
.NAME_BASIONYM_EX_AUTHORSHIP
)] = teamToString(name
.getExBasionymAuthorship());
1092 //basionymAuthorshipYear
1093 csvLine
[table
.getIndex(ColDpExportTable
.NAME_BASIONYM_AUTHORSHIP_YEAR
)] =
1094 basionym
== null?
null :
1095 basionym
.getNomenclaturalReference() == null ?
null :
1096 basionym
.getNomenclaturalReference().getYear();
1099 csvLine
[table
.getIndex(ColDpExportTable
.RANK
)] = state
.getTransformer().getCacheByRank(rank
);
1102 if (name
.isGenusOrSupraGeneric()) {
1103 csvLine
[table
.getIndex(ColDpExportTable
.NAME_UNINOMIAL
)] = name
.getGenusOrUninomial();
1105 csvLine
[table
.getIndex(ColDpExportTable
.NAME_GENUS
)] = name
.getGenusOrUninomial();
1108 csvLine
[table
.getIndex(ColDpExportTable
.NAME_INFRAGENERIC_EPITHET
)] = name
.getInfraGenericEpithet();
1109 csvLine
[table
.getIndex(ColDpExportTable
.NAME_SPECIFIC_EPITHET
)] = name
.getSpecificEpithet();
1110 csvLine
[table
.getIndex(ColDpExportTable
.NAME_INFRASPECIFIC_EPITHET
)] = name
.getInfraSpecificEpithet();
1112 //TODO 3 name cultivar epithet, group epithet
1113 csvLine
[table
.getIndex(ColDpExportTable
.NAME_CULTIVAR_EPITHET
)] = name
.getCultivarEpithet();
1116 csvLine
[table
.getIndex(ColDpExportTable
.NAME_CODE
)] = state
.getTransformer().getCacheByNomenclaturalCode(name
.getNameType());
1118 //TODO 5 name status, is this handling correct?
1119 //Also according to documentation we should put more detailed status information to the remarks field
1120 // or an URI from the NOMEN ontology could be used
1121 if (name
.getStatus() == null || name
.getStatus().isEmpty()) {
1122 csvLine
[table
.getIndex(ColDpExportTable
.NAME_STATUS
)] = "acceptable";
1124 NomenclaturalStatus status
= name
.getStatus().iterator().next();
1125 if (name
.getStatus().size() > 1) {
1126 String message
= "There is >1 name status for " + name
.getTitleCache();
1127 state
.getResult().addWarning(message
);
1129 String statusTypeString
= state
.getTransformer().getCacheByNomStatus(status
.getType());
1130 csvLine
[table
.getIndex(ColDpExportTable
.NAME_STATUS
)] = statusTypeString
;
1131 if (statusTypeString
== null) {
1132 String message
= "Name status " + status
.getType() + " not yet handled for name " + name
.getTitleCache();
1133 state
.getResult().addWarning(message
);
1138 Reference nomRef
= name
.getNomenclaturalReference();
1139 if (nomRef
!= null) {
1140 csvLine
[table
.getIndex(ColDpExportTable
.REFERENCE_ID
)] = getId(state
, nomRef
);
1141 handleReference(state
, nomRef
);
1144 if (nomRef
.getDatePublished() != null) {
1145 csvLine
[table
.getIndex(ColDpExportTable
.NAME_PUBLISHED_IN_YEAR
)] = nomRef
.getDatePublished().getYear();
1147 nomRef
= HibernateProxyHelper
.deproxy(nomRef
);
1148 if (nomRef
.getInReference() != null) {
1149 Reference inReference
= nomRef
.getInReference();
1150 if (inReference
.getDatePublished() != null && nomRef
.getDatePublished() == null) {
1151 csvLine
[table
.getIndex(ColDpExportTable
.NAME_PUBLISHED_IN_YEAR
)]
1152 = inReference
.getDatePublished().getYear();
1158 if (name
.getNomenclaturalMicroReference() != null) {
1159 csvLine
[table
.getIndex(ColDpExportTable
.NAME_PUBLISHED_IN_PAGE
)] = name
.getNomenclaturalMicroReference();
1162 //publishedInPageLink
1163 String protologueUriString
= extractProtologueURIs(state
, name
);
1164 csvLine
[table
.getIndex(ColDpExportTable
.NAME_PUBLISHED_IN_PAGE_LINK
)] = protologueUriString
;
1166 //TODO 2 name links - do we have this in CDM?
1169 csvLine
[table
.getIndex(ColDpExportTable
.REMARKS
)] = getRemarks(name
);
1171 handleTypeMaterial(state
, name
);
1174 state
.getProcessor().put(table
, name
, csvLine
);
1175 //TODO 1 nameRelationships - is this still an open issue? Do tests exist?
1176 handleNameRelationships(state
, name
);
1178 } catch (Exception e
) {
1179 state
.getResult().addException(e
,
1180 "An unexpected error occurred when handling the name " + cdmBaseStr(name
) + ": " + name
.getTitleCache() + ": " + e
.getMessage());
1182 e
.printStackTrace();
1186 private String
teamToString(TeamOrPersonBase
<?
> author
) {
1187 if (author
== null) {
1190 String nomCache
= author
.getNomenclaturalTitleCache();
1191 if (StringUtils
.isEmpty(nomCache
)){
1197 .replace(" & ", "|")
1199 .replace(" et ", "|");
1203 private void handleTypeMaterial(ColDpExportState state
, TaxonName name
) {
1205 ColDpExportTable table
= ColDpExportTable
.TYPE_MATERIAL
;
1206 String
[] csvLine
= new String
[table
.getSize()];
1208 Collection
<TypeDesignationBase
> specimenTypeDesignations
= new ArrayList
<>();
1209 List
<TextualTypeDesignation
> textualTypeDesignations
= new ArrayList
<>();
1211 for (TypeDesignationBase
<?
> typeDesignation
: name
.getTypeDesignations()) {
1212 if (typeDesignation
.isInstanceOf(TextualTypeDesignation
.class)) {
1213 if (((TextualTypeDesignation
) typeDesignation
).isVerbatim() ){
1214 Set
<IdentifiableSource
> sources
= typeDesignation
.getSources();
1215 boolean isProtologue
= false;
1216 if (sources
!= null && !sources
.isEmpty()){
1217 IdentifiableSource source
= sources
.iterator().next();
1218 if (name
.getNomenclaturalReference() != null){
1219 isProtologue
= source
.getCitation() != null? source
.getCitation().getUuid().equals(name
.getNomenclaturalReference().getUuid()): false;
1223 csvLine
[table
.getIndex(ColDpExportTable
.TYPE_CITATION
)] = ((TextualTypeDesignation
) typeDesignation
)
1224 .getPreferredText(Language
.DEFAULT());
1226 //TODO 2 specimen type textual type designation, still open?
1227 textualTypeDesignations
.add((TextualTypeDesignation
) typeDesignation
);
1230 ///TODO 2 specimen type textual type designation, still open?
1231 textualTypeDesignations
.add((TextualTypeDesignation
) typeDesignation
);
1233 } else if (typeDesignation
.isInstanceOf(SpecimenTypeDesignation
.class)) {
1234 SpecimenTypeDesignation specimenType
= HibernateProxyHelper
.deproxy(typeDesignation
, SpecimenTypeDesignation
.class);
1235 specimenTypeDesignations
.add(specimenType
);
1236 handleSpecimenType(state
, specimenType
, csvLine
, table
, name
);
1237 }else if (typeDesignation
instanceof NameTypeDesignation
){
1239 // specimenTypeDesignations.add(HibernateProxyHelper.deproxy(typeDesignation, NameTypeDesignation.class));
1243 TypeDesignationSetContainer typeContainer
= new TypeDesignationSetContainer(specimenTypeDesignations
, name
, TypeDesignationSetComparator
.ORDER_BY
.TYPE_STATUS
);
1244 HTMLTagRules rules
= new HTMLTagRules();
1245 //rules.addRule(TagEnum.name, "i");
1246 csvLine
[table
.getIndex(ColDpExportTable
.TYPE_CITATION
)] = typeContainer
.print(false, false, false, rules
);
1248 //TODO 2 type material what is this second type computation? Is it only about sources?
1249 StringBuilder stringbuilder
= new StringBuilder();
1251 for (TextualTypeDesignation typeDesignation
: textualTypeDesignations
) {
1252 stringbuilder
.append(typeDesignation
.getPreferredText(Language
.DEFAULT()));
1253 if (typeDesignation
.getSources() != null && !typeDesignation
.getSources().isEmpty() ){
1254 stringbuilder
.append( " [");
1256 for (IdentifiableSource source
: typeDesignation
.getSources()){
1257 if (source
.getCitation() != null){
1258 stringbuilder
.append(OriginalSourceFormatter
.INSTANCE
.format(source
));
1260 if (index
< typeDesignation
.getSources().size()) {
1261 stringbuilder
.append( ", ");
1265 stringbuilder
.append( "]");
1267 if (i
< textualTypeDesignations
.size()) {
1268 stringbuilder
.append( "; ");
1270 stringbuilder
.append(".");
1274 csvLine
[table
.getIndex(ColDpExportTable
.TYPE_CITATION
)] = stringbuilder
.toString();
1275 } catch (Exception e
) {
1276 state
.getResult().addException(e
,
1277 "An unexpected error occurred when handling the type designations for name " + cdmBaseStr(name
) + ": " + name
.getTitleCache() + ": " + e
.getMessage());
1278 e
.printStackTrace();
1282 //TODO 2 specimen type what is the difference to handleSpecimenType()
1283 // private void handleSpecimenType_(ColDpExportState state, SpecimenTypeDesignation specimenType) {
1285 // if (specimenType.getTypeSpecimen() != null){
1286 // DerivedUnit specimen = specimenType.getTypeSpecimen();
1287 // if(specimen != null && !state.getSpecimenStore().contains( specimen.getUuid())){
1288 // handleSpecimen(state, specimen);
1292 // String[] csvLine = new String[table.getSize()];
1293 // //TYPE_ID, SPECIMEN_FK, TYPE_VERBATIM_CITATION, TYPE_STATUS, TYPE_DESIGNATED_BY_STRING, TYPE_DESIGNATED_BY_REF_FK};
1294 // //Specimen_Fk und den Typusangaben (Art des Typus [holo, lecto, etc.], Quelle, Designation-Quelle, +
1295 // Set<TaxonName> typifiedNames = specimenType.getTypifiedNames();
1296 // for (TaxonName name: typifiedNames){
1297 // csvLine[table.getIndex(ColDpExportTable.TYPE_STATUS)] = specimenType.getTypeStatus() != null? specimenType.getTypeStatus().getDescription(): "";
1298 // csvLine[table.getIndex(ColDpExportTable.TYPE_ID)] = getId(state, specimenType);
1299 // csvLine[table.getIndex(ColDpExportTable.TYPIFIED_NAME_FK)] = getId(state, name);
1300 // csvLine[table.getIndex(ColDpExportTable.SPECIMEN_FK)] = getId(state, specimenType.getTypeSpecimen());
1301 // if (specimenType.getSources() != null && !specimenType.getSources().isEmpty()){
1302 // String sourceString = "";
1304 // for (IdentifiableSource source: specimenType.getSources()){
1305 // if (source.getCitation()!= null){
1306 // sourceString = sourceString.concat(source.getCitation().getCitation());
1309 // if (index != specimenType.getSources().size()){
1310 // sourceString.concat(", ");
1313 // csvLine[table.getIndex(ColDpExportTable.TYPE_INFORMATION_REF_STRING)] = sourceString;
1315 // if (specimenType.getDesignationSource() != null && specimenType.getDesignationSource().getCitation() != null && !state.getReferenceStore().contains(specimenType.getDesignationSource().getCitation().getUuid())){
1316 // handleReference(state, specimenType.getDesignationSource().getCitation());
1317 // csvLine[table.getIndex(ColDpExportTable.TYPE_DESIGNATED_BY_REF_FK)] = specimenType.getDesignationSource() != null ? getId(state, specimenType.getDesignationSource().getCitation()): "";
1320 // state.getProcessor().put(table, specimenType, csvLine);
1324 private void handleSpecimenType(ColDpExportState state
, SpecimenTypeDesignation specimenType
, String
[] csvLine
, ColDpExportTable table
, TaxonName name
) {
1328 DerivedUnit specimen
= specimenType
.getTypeSpecimen();
1329 if (specimenType
.getTypeSpecimen() == null){
1331 //handleSpecimen(state, specimen);
1334 //ID - TODO 3 specimen type best use dwc:occurrenceID
1335 csvLine
[table
.getIndex(ColDpExportTable
.ID
)] = getId(state
, specimen
);
1337 //TODO 9 specimenType sourceID //handled in referenceID
1338 csvLine
[table
.getIndex(ColDpExportTable
.SOURCE_ID
)] = null;
1341 Set
<TaxonName
> typifiedNames
= specimenType
.getTypifiedNames();
1342 if (typifiedNames
.size() > 1){
1343 //TODO 3 specimen type we should
1344 state
.getResult().addWarning("Please check the specimen type "
1345 + cdmBaseStr(specimenType
) + " there are more then one typified name.");
1347 // if (typifiedNames.iterator().hasNext()){
1348 // TaxonName name = typifiedNames.iterator().next();
1349 csvLine
[table
.getIndex(ColDpExportTable
.TYPE_NAMEID
)] = getId(state
, name
);
1352 //TODO 3 specimen type citation - also done in calling method
1353 csvLine
[table
.getIndex(ColDpExportTable
.TYPE_CITATION
)] = specimen
.getTitleCache();
1356 //TODO 3 specimen type type status transformation
1357 csvLine
[table
.getIndex(ColDpExportTable
.TYPE_STATUS
)] = specimenType
.getTypeStatus() != null? specimenType
.getTypeStatus().getDescription(): "";
1359 //TODO 2 specimen type referenceID - see description, should be designation ref id or original name refid
1360 if (specimenType
.getDesignationSource() != null && specimenType
.getDesignationSource().getCitation() != null && !state
.getReferenceStore().contains(specimenType
.getDesignationSource().getCitation().getUuid())){
1361 //TODO 3 specimen type, should be source, not reference; why?
1362 handleReference(state
, specimenType
.getDesignationSource().getCitation());
1363 csvLine
[table
.getIndex(ColDpExportTable
.REFERENCE_ID
)] = specimenType
.getDesignationSource() != null ?
getId(state
, specimenType
.getDesignationSource().getCitation()): "";
1367 if (specimen
.getCollection() != null) {
1368 //TODO 3 specimen type institution code not available handling
1369 csvLine
[table
.getIndex(ColDpExportTable
.TYPE_INSTITUTION_CODE
)] = specimen
.getCollection().getCode();
1373 if (specimen
.isInstanceOf(DerivedUnit
.class)){
1374 DerivedUnit derivedUnit
= specimen
;
1375 String catalogNumber
= null;
1376 if (!StringUtils
.isBlank(derivedUnit
.getBarcode())){
1377 catalogNumber
= derivedUnit
.getBarcode();
1378 } else if (!StringUtils
.isBlank(derivedUnit
.getAccessionNumber())){
1379 catalogNumber
= derivedUnit
.getAccessionNumber();
1380 } else if (!StringUtils
.isBlank(derivedUnit
.getCatalogNumber())){
1381 catalogNumber
= derivedUnit
.getCatalogNumber();
1383 csvLine
[table
.getIndex(ColDpExportTable
.TYPE_CATALOG_NUMBER
)] = catalogNumber
;
1386 //TODO 9 specimen type associatedSequences - not yet implemented
1387 csvLine
[table
.getIndex(ColDpExportTable
.TYPE_ASSOC_SEQ
)] = null;
1390 if (specimen
.getSex() != null) {
1391 //TODO 7 specimen type transform sex, we usually don't have specimen with sex
1392 csvLine
[table
.getIndex(ColDpExportTable
.TYPE_SEX
)] = specimen
.getSex().getLabel();
1396 if (specimen
.getPreferredStableUri() != null) {
1397 csvLine
[table
.getIndex(ColDpExportTable
.LINK
)] = specimen
.getPreferredStableUri().toString();
1401 //TODO 3 specimen type gather remarks on type designation, field unit(s) and specimen
1402 csvLine
[table
.getIndex(ColDpExportTable
.REMARKS
)] = getRemarks(specimen
);
1405 //TODO 3 specimen type performance due to service call
1406 Collection
<FieldUnit
> fieldUnits
= this.getOccurrenceService().findFieldUnits(specimen
.getUuid(), null);
1407 if (!fieldUnits
.isEmpty()) {
1408 if (fieldUnits
.size() > 1) {
1409 state
.getResult().addWarning("There are >1 field units for specimen "
1410 + cdmBaseStr(specimen
) + ".");
1413 FieldUnit fieldUnit
= fieldUnits
.iterator().next();
1415 GatheringEvent gathering
= fieldUnit
.getGatheringEvent();
1416 if (gathering
!= null) {
1417 handleGatheringEvent(state
, csvLine
, table
, fieldUnit
, gathering
);
1421 state
.getProcessor().put(table
, specimenType
, csvLine
);
1422 }catch (Exception e
) {
1423 state
.getResult().addException(e
,
1424 "An unexpected error occurred when handling type material for name " + cdmBaseStr(name
) + ": " + name
.getTitleCache() + ": " + e
.getMessage());
1425 e
.printStackTrace();
1429 private void handleGatheringEvent(ColDpExportState state
, String
[] csvLine
, ColDpExportTable table
,
1430 FieldUnit fieldUnit
, GatheringEvent gathering
) {
1432 if (gathering
.getLocality() != null) {
1433 csvLine
[table
.getIndex(ColDpExportTable
.TYPE_LOCALITY
)]
1434 = gathering
.getLocality().getText();
1436 //TODO 3 gathering include areas, see CDM-light implementation and COL-DP description
1439 if (gathering
.getCountry() != null) {
1440 csvLine
[table
.getIndex(ColDpExportTable
.TYPE_COUNTRY
)]
1441 = gathering
.getCountry().getLabel();
1445 Point point
= gathering
.getExactLocation();
1446 if (point
!= null) {
1448 if (point
.getLatitude() != null) {
1449 //TODO 3 gathering rounding
1450 csvLine
[table
.getIndex(ColDpExportTable
.TYPE_LATITUDE
)]
1451 = point
.getLatitude().toString();
1454 if (point
.getLongitude() != null) {
1455 //TODO 3 gathering rounding
1456 csvLine
[table
.getIndex(ColDpExportTable
.TYPE_LONGITUDE
)]
1457 = point
.getLongitude().toString();
1462 if (gathering
.getAbsoluteElevation() != null) {
1463 //TODO 3 type specimen include max/text/depth
1464 csvLine
[table
.getIndex(ColDpExportTable
.TYPE_ALTITUDE
)]
1465 = gathering
.getAbsoluteElevation().toString();
1468 //host - does more or less not exist in CDM
1469 csvLine
[table
.getIndex(ColDpExportTable
.TYPE_HOST
)] = null;
1472 if (gathering
.getGatheringDate() != null) {
1473 //TODO 3 specimen type ISO 8601
1474 csvLine
[table
.getIndex(ColDpExportTable
.TYPE_DATE
)] = gathering
1475 .getGatheringDate().toString();
1479 csvLine
[table
.getIndex(ColDpExportTable
.TYPE_COLLECTOR
)]
1480 = createCollectorString(state
, gathering
, fieldUnit
);
1481 //field number not yet in COL-DP
1482 //csvLine[table.getIndex(ColDpExportTable.COLLECTOR_NUMBER)] = fieldUnit.getFieldNumber();
1485 private String
createNameWithItalics(List
<TaggedText
> taggedName
) {
1487 String fullTitleWithHtml
= "";
1488 for (TaggedText taggedText
: taggedName
){
1489 if (taggedText
.getType().equals(TagEnum
.name
)){
1490 fullTitleWithHtml
+= "<i>" + taggedText
.getText() + "</i> ";
1491 }else if (taggedText
.getType().equals(TagEnum
.separator
)){
1492 fullTitleWithHtml
= fullTitleWithHtml
.trim() + taggedText
.getText() ;
1494 fullTitleWithHtml
+= taggedText
.getText() + " ";
1497 return fullTitleWithHtml
;
1500 private void handleNameRelationships(ColDpExportState state
, TaxonName name
) {
1501 ColDpExportTable table
= ColDpExportTable
.NAME_RELATION
;
1502 ColDpExportTransformer transformer
= (ColDpExportTransformer
)state
.getTransformer();
1504 //relations in which "name" is the from name
1505 Set
<NameRelationship
> fromRels
= name
.getRelationsFromThisName();
1506 for (NameRelationship rel
: fromRels
) {
1507 ColDpNameRelType coldpType
= transformer
.getColDpNameRelTypeByNameRelationType(rel
.getType());
1508 if (coldpType
== null) {
1509 handleNoColDpNameRelType(state
, rel
.getType(), name
);
1511 }else if (coldpType
.getDirection() == 0) {
1512 continue; //the relation is handled the other way round if necessary
1515 TaxonName name2
= CdmBase
.deproxy(rel
.getToName());
1516 handleRelNameCommonData(state
, table
, rel
, name
, name2
, coldpType
);
1519 //relations in which "name" is the toName
1520 Set
<NameRelationship
> toRels
= name
.getRelationsToThisName();
1521 for (NameRelationship rel
: toRels
) {
1522 ColDpNameRelType coldpType
= transformer
.getColDpNameRelTypeByNameRelationType(rel
.getType());
1523 if (coldpType
== null) {
1524 handleNoColDpNameRelType(state
, rel
.getType(), name
);
1526 }else if (coldpType
.getDirection() == 1) {
1527 continue; //the relation is handled the other way round if necessary
1530 TaxonName name2
= CdmBase
.deproxy(rel
.getFromName());
1531 handleRelNameCommonData(state
, table
, rel
, name
, name2
, coldpType
);
1533 } catch (Exception e
) {
1534 state
.getResult().addException(e
,
1535 "An unexpected error occurred when handling name relationships for name "
1536 + cdmBaseStr(name
) + ": " + name
.getTitleCache() + ": " + e
.getMessage());
1537 e
.printStackTrace();
1541 private void handleNoColDpNameRelType(ColDpExportState state
, NameRelationshipType nameRelType
, TaxonName taxonName
) {
1543 if (nameRelType
== null) {
1544 warning
= "Name relationship has not type for name " + taxonName
.getTitleCache();
1546 //TODO misspelling, alternative name, blocking name for, avoids homonym of, unspecific "non"
1547 warning
= "Name relationship type not yet handled by COL-DP: " + nameRelType
.getTitleCache() + "; name: " + taxonName
.getTitleCache();
1549 state
.getResult().addWarning(warning
);
1552 private void handleRelNameCommonData(ColDpExportState state
, ColDpExportTable table
,
1553 NameRelationship rel
, TaxonName name
, TaxonName relatedName
, ColDpNameRelType coldpType
) {
1555 String
[] csvLine
= new String
[table
.getSize()];
1557 if (!state
.getNameStore().containsKey(relatedName
.getId())) {
1558 handleName(state
, relatedName
, null);
1560 csvLine
[table
.getIndex(ColDpExportTable
.REL_NAME_NAMEID
)] = getId(state
, name
);
1561 csvLine
[table
.getIndex(ColDpExportTable
.REL_NAME_REL_NAMEID
)] = getId(state
, relatedName
);
1563 csvLine
[table
.getIndex(ColDpExportTable
.TYPE
)] = coldpType
.getLabel();
1564 csvLine
[table
.getIndex(ColDpExportTable
.SOURCE_ID
)] = null;
1565 if (rel
.getCitation() != null) {
1566 handleReference(state
, rel
.getCitation());
1567 csvLine
[table
.getIndex(ColDpExportTable
.REFERENCE_ID
)] = getId(state
, rel
.getCitation());
1570 csvLine
[table
.getIndex(ColDpExportTable
.REMARKS
)] = getRemarks(rel
);
1571 state
.getProcessor().put(table
, rel
.getUuid().toString(), csvLine
);
1574 private String
getVolume(Reference reference
) {
1575 if (reference
.getVolume() != null) {
1576 return reference
.getVolume();
1577 } else if (reference
.getInReference() != null) {
1578 if (reference
.getInReference().getVolume() != null) {
1579 return reference
.getInReference().getVolume();
1585 // private void handleIdentifier(ColDpExportState state, CdmBase cdmBase) {
1586 // ColDpExportTable table = ColDpExportTable.IDENTIFIER;
1587 // String[] csvLine;
1589 // if (cdmBase instanceof TaxonName){
1590 // TaxonName name = (TaxonName)cdmBase;
1593 // List<Identifier> identifiers = name.getIdentifiers();
1595 // //first check which kind of identifiers are available and then sort and create table entries
1596 // Map<IdentifierType, Set<Identifier>> identifierTypes = new HashMap<>();
1597 // for (Identifier identifier: identifiers){
1598 // IdentifierType type = identifier.getType();
1599 // if (identifierTypes.containsKey(type)){
1600 // identifierTypes.get(type).add(identifier);
1602 // Set<Identifier> tempList = new HashSet<>();
1603 // tempList.add(identifier);
1604 // identifierTypes.put(type, tempList);
1608 // for (IdentifierType type:identifierTypes.keySet()){
1609 // Set<Identifier> identifiersByType = identifierTypes.get(type);
1610 // csvLine = new String[table.getSize()];
1611 // csvLine[table.getIndex(ColDpExportTable.FK)] = getId(state, name);
1612 // csvLine[table.getIndex(ColDpExportTable.REF_TABLE)] = "ScientificName";
1613 // csvLine[table.getIndex(ColDpExportTable.IDENTIFIER_TYPE)] = type.getLabel();
1614 // csvLine[table.getIndex(ColDpExportTable.EXTERNAL_NAME_IDENTIFIER)] = extractIdentifier(
1615 // identifiersByType);
1616 // state.getProcessor().put(table, name.getUuid() + ", " + type.getLabel(), csvLine);
1620 //// Set<String> IPNIidentifiers = name.getIdentifiers(DefinedTerm.IDENTIFIER_NAME_IPNI());
1621 //// Set<String> tropicosIdentifiers = name.getIdentifiers(DefinedTerm.IDENTIFIER_NAME_TROPICOS());
1622 //// Set<String> WFOIdentifiers = name.getIdentifiers(DefinedTerm.uuidWfoNameIdentifier);
1623 //// if (!IPNIidentifiers.isEmpty()) {
1624 //// csvLine = new String[table.getSize()];
1625 //// csvLine[table.getIndex(CdmLightExportTable.FK)] = getId(state, name);
1626 //// csvLine[table.getIndex(CdmLightExportTable.REF_TABLE)] = "ScientificName";
1627 //// csvLine[table.getIndex(CdmLightExportTable.IDENTIFIER_TYPE)] = IPNI_NAME_IDENTIFIER;
1628 //// csvLine[table.getIndex(CdmLightExportTable.EXTERNAL_NAME_IDENTIFIER)] = extractIdentifier(
1629 //// IPNIidentifiers);
1630 //// state.getProcessor().put(table, name.getUuid() + ", " + IPNI_NAME_IDENTIFIER, csvLine);
1632 //// if (!tropicosIdentifiers.isEmpty()) {
1633 //// csvLine = new String[table.getSize()];
1634 //// csvLine[table.getIndex(CdmLightExportTable.FK)] = getId(state, name);
1635 //// csvLine[table.getIndex(CdmLightExportTable.REF_TABLE)] = "ScientificName";
1636 //// csvLine[table.getIndex(CdmLightExportTable.IDENTIFIER_TYPE)] = TROPICOS_NAME_IDENTIFIER;
1637 //// csvLine[table.getIndex(CdmLightExportTable.EXTERNAL_NAME_IDENTIFIER)] = extractIdentifier(
1638 //// tropicosIdentifiers);
1639 //// state.getProcessor().put(table, name.getUuid() + ", " + IPNI_NAME_IDENTIFIER, csvLine);
1641 //// if (!WFOIdentifiers.isEmpty()) {
1642 //// csvLine = new String[table.getSize()];
1643 //// csvLine[table.getIndex(CdmLightExportTable.FK)] = getId(state, name);
1644 //// csvLine[table.getIndex(CdmLightExportTable.REF_TABLE)] = "ScientificName";
1645 //// csvLine[table.getIndex(CdmLightExportTable.IDENTIFIER_TYPE)] = WFO_NAME_IDENTIFIER;
1646 //// csvLine[table.getIndex(CdmLightExportTable.EXTERNAL_NAME_IDENTIFIER)] = extractIdentifier(
1647 //// WFOIdentifiers);
1648 //// state.getProcessor().put(table, name.getUuid() + ", " + WFO_NAME_IDENTIFIER, csvLine);
1650 // }catch(Exception e){
1651 // state.getResult().addWarning("Please check the identifiers for "
1652 // + cdmBaseStr(cdmBase) + " maybe there is an empty identifier");
1657 // if (cdmBase instanceof IdentifiableEntity){
1658 // IdentifiableEntity<?> identifiableEntity = (IdentifiableEntity<?>) cdmBase;
1659 // List<Identifier> identifiers = identifiableEntity.getIdentifiers();
1660 // String tableName = null;
1661 // if (cdmBase instanceof Reference){
1662 // tableName = "Reference";
1663 // }else if (cdmBase instanceof SpecimenOrObservationBase){
1664 // tableName = "Specimen";
1665 // }else if (cdmBase instanceof Taxon){
1666 // tableName = "Taxon";
1667 // }else if (cdmBase instanceof Synonym){
1668 // tableName = "Synonym";
1669 // }else if (cdmBase instanceof TeamOrPersonBase){
1670 // tableName = "PersonOrTeam";
1673 // for (Identifier identifier: identifiers){
1674 // if (identifier.getType() == null && identifier.getIdentifier() == null){
1675 // state.getResult().addWarning("Please check the identifiers for "
1676 // + cdmBaseStr(cdmBase) + " there is an empty identifier");
1680 // csvLine = new String[table.getSize()];
1681 // csvLine[table.getIndex(ColDpExportTable.FK)] = getId(state, cdmBase);
1683 // if (tableName != null){
1684 // csvLine[table.getIndex(ColDpExportTable.REF_TABLE)] = tableName;
1685 // csvLine[table.getIndex(ColDpExportTable.IDENTIFIER_TYPE)] = identifier.getType() != null? identifier.getType().getLabel():null;
1686 // csvLine[table.getIndex(ColDpExportTable.EXTERNAL_NAME_IDENTIFIER)] = identifier.getIdentifier();
1687 // state.getProcessor().put(table, cdmBase.getUuid() + (identifier.getType() != null? identifier.getType().getLabel():null), csvLine);
1690 // if (cdmBase instanceof Reference ){
1691 // Reference ref = (Reference)cdmBase;
1692 // if (ref.getDoi() != null){
1693 // csvLine = new String[table.getSize()];
1694 // csvLine[table.getIndex(ColDpExportTable.FK)] = getId(state, cdmBase);
1695 // csvLine[table.getIndex(ColDpExportTable.REF_TABLE)] = tableName;
1696 // csvLine[table.getIndex(ColDpExportTable.IDENTIFIER_TYPE)] = "DOI";
1697 // csvLine[table.getIndex(ColDpExportTable.EXTERNAL_NAME_IDENTIFIER)] = ref.getDoiString();
1698 // state.getProcessor().put(table, cdmBase.getUuid() + "DOI", csvLine);
1702 // if (cdmBase instanceof TeamOrPersonBase){
1703 // TeamOrPersonBase<?> person= HibernateProxyHelper.deproxy(cdmBase, TeamOrPersonBase.class);
1704 // if (person instanceof Person && ((Person)person).getOrcid() != null){
1705 // csvLine = new String[table.getSize()];
1706 // csvLine[table.getIndex(ColDpExportTable.FK)] = getId(state, cdmBase);
1707 // csvLine[table.getIndex(ColDpExportTable.REF_TABLE)] = tableName;
1708 // csvLine[table.getIndex(ColDpExportTable.IDENTIFIER_TYPE)] = "ORCID";
1709 // csvLine[table.getIndex(ColDpExportTable.EXTERNAL_NAME_IDENTIFIER)]= ((Person)person).getOrcid().asURI();
1710 // state.getProcessor().put(table, cdmBase.getUuid() + "ORCID", csvLine);
1715 // } catch (Exception e) {
1716 // state.getResult().addException(e, "An unexpected error occurred when handling identifiers for "
1717 // + cdmBaseStr(cdmBase) + ": " + e.getMessage());
1718 // e.printStackTrace();
1722 // private String extractIdentifier(Set<Identifier> identifierSet) {
1724 // String identifierString = "";
1725 // for (Identifier identifier : identifierSet) {
1726 // if (!StringUtils.isBlank(identifierString)) {
1727 // identifierString += ", ";
1729 // identifierString += identifier.getIdentifier();
1731 // return identifierString;
1734 private String
extractProtologueURIs(ColDpExportState state
, TaxonName name
) {
1735 if (name
.getNomenclaturalSource() != null){
1736 Set
<ExternalLink
> links
= name
.getNomenclaturalSource().getLinks();
1737 return extractLinkUris(links
.iterator());
1743 private String
extractMediaURIs(ColDpExportState state
, Set
<?
extends DescriptionBase
<?
>> descriptionsSet
,
1746 String mediaUriString
= "";
1747 Set
<DescriptionElementBase
> elements
= new HashSet
<>();
1748 for (DescriptionBase
<?
> description
: descriptionsSet
) {
1750 if (!description
.getElements().isEmpty()) {
1751 elements
= description
.getElements();
1753 for (DescriptionElementBase element
: elements
) {
1754 Feature entityFeature
= HibernateProxyHelper
.deproxy(element
.getFeature());
1755 if (entityFeature
.equals(feature
)) {
1756 if (!element
.getMedia().isEmpty()) {
1757 List
<Media
> media
= element
.getMedia();
1758 for (Media mediaElement
: media
) {
1759 Iterator
<MediaRepresentation
> it
= mediaElement
.getRepresentations().iterator();
1760 mediaUriString
= extractMediaUris(it
);
1766 } catch (Exception e
) {
1767 state
.getResult().addException(e
, "An unexpected error occurred when extracting media URIs for "
1768 + cdmBaseStr(description
) + ": " + e
.getMessage());
1771 return mediaUriString
;
1775 private String
extractStatusString(ColDpExportState state
, TaxonName name
, boolean abbrev
) {
1777 Set
<NomenclaturalStatus
> status
= name
.getStatus();
1778 if (status
.isEmpty()) {
1781 String statusString
= "";
1782 for (NomenclaturalStatus nameStatus
: status
) {
1783 if (nameStatus
!= null) {
1785 if (nameStatus
.getType() != null) {
1786 statusString
+= nameStatus
.getType().getIdInVocabulary();
1789 if (nameStatus
.getType() != null) {
1790 statusString
+= nameStatus
.getType().getTitleCache();
1795 if (nameStatus
.getRuleConsidered() != null
1796 && !StringUtils
.isBlank(nameStatus
.getRuleConsidered())) {
1797 statusString
+= ": " + nameStatus
.getRuleConsidered();
1799 if (nameStatus
.getCitation() != null) {
1800 String shortCitation
= OriginalSourceFormatter
.INSTANCE
.format(nameStatus
.getCitation(), null);
1801 statusString
+= " (" + shortCitation
+ ")";
1803 // if (nameStatus.getCitationMicroReference() != null
1804 // && !StringUtils.isBlank(nameStatus.getCitationMicroReference())) {
1805 // statusString += " " + nameStatus.getCitationMicroReference();
1808 statusString
+= " ";
1811 return statusString
;
1812 } catch (Exception e
) {
1813 state
.getResult().addException(e
, "An unexpected error occurred when extracting status string for "
1814 + cdmBaseStr(name
) + ": " + e
.getMessage());
1819 private void handleHomotypicalGroup(ColDpExportState state
, HomotypicalGroup group
, Taxon acceptedTaxon
) {
1822 List
<TaxonName
> typifiedNames
= new ArrayList
<>();
1823 if (acceptedTaxon
!= null){
1824 List
<Synonym
> synonymsInGroup
= acceptedTaxon
.getSynonymsInGroup(group
);
1825 if (group
.equals(acceptedTaxon
.getHomotypicGroup())){
1826 typifiedNames
.add(acceptedTaxon
.getName());
1828 synonymsInGroup
.stream().forEach(synonym
-> typifiedNames
.add(CdmBase
.deproxy(synonym
.getName())));
1832 TaxonName firstname
= null;
1833 for (TaxonName name
: typifiedNames
){
1834 Iterator
<Taxon
> taxa
= name
.getTaxa().iterator();
1835 while(taxa
.hasNext()){
1836 Taxon taxon
= taxa
.next();
1837 if(!(taxon
.isMisapplication() || taxon
.isProparteSynonym())){
1844 //// Collections.sort(typifiedNames, new HomotypicalGroupNameComparator(firstname, true));
1845 // String typifiedNamesString = "";
1846 // String typifiedNamesWithSecString = "";
1847 // String typifiedNamesWithoutAccepted = "";
1848 // String typifiedNamesWithoutAcceptedWithSec = "";
1850 // for (TaxonName name : typifiedNames) {
1851 // // Concatenated output string for homotypic group (names and
1852 // // citations) + status + some name relations (e.g. “non”)
1853 // // TODO 3 commented code - can this be deleted? -- : nameRelations, which and how to display
1854 // Set<TaxonBase> taxonBases = name.getTaxonBases();
1855 // TaxonBase<?> taxonBase;
1858 // String nameString = name.getFullTitleCache();
1859 // String doubtful = "";
1861 // if (state.getConfig().isAddHTML()){
1862 // nameString = createNameWithItalics(name.getTaggedFullTitle()) ;
1865 // Set<NameRelationship> related = name.getNameRelations();
1866 // List<NameRelationship> relatedList = new ArrayList<>(related);
1868 // Collections.sort(relatedList, (nr1, nr2)-> {
1869 // return nr1.getType().compareTo(nr2.getType());});
1871 // List<NameRelationship> nonNames = new ArrayList<>();
1872 // List<NameRelationship> otherRelationships = new ArrayList<>();
1874 // for (NameRelationship rel: relatedList){
1875 // //no inverse relations
1876 // if (rel.getFromName().equals(name)){
1877 // // alle Homonyme und inverse blocking names
1878 // if (rel.getType().equals(NameRelationshipType.LATER_HOMONYM())
1879 // || rel.getType().equals(NameRelationshipType.TREATED_AS_LATER_HOMONYM())
1880 // || (rel.getType().equals(NameRelationshipType.BLOCKING_NAME_FOR()))
1881 // || (rel.getType().equals(NameRelationshipType.UNSPECIFIC_NON()))
1882 // || (rel.getType().equals(NameRelationshipType.AVOIDS_HOMONYM_OF()))
1884 // nonNames.add(rel);
1885 // }else if (!rel.getType().isBasionymRelation()){
1886 // otherRelationships.add(rel);
1889 // if (state.getConfig().isShowInverseNameRelationsInHomotypicGroup()) {
1890 // if (rel.getToName().equals(name)){
1891 // // alle Homonyme und inverse blocking names
1892 //// if (rel.getType().equals(NameRelationshipType.LATER_HOMONYM())
1893 //// || rel.getType().equals(NameRelationshipType.TREATED_AS_LATER_HOMONYM())
1894 //// || (rel.getType().equals(NameRelationshipType.BLOCKING_NAME_FOR()))
1895 //// || (rel.getType().equals(NameRelationshipType.UNSPECIFIC_NON()))
1896 //// || (rel.getType().equals(NameRelationshipType.AVOIDS_HOMONYM_OF()))
1898 //// nonNames.add(rel);
1899 //// }else if (!rel.getType().isBasionymRelation()){
1900 // otherRelationships.add(rel);
1906 // String nonRelNames = "";
1907 // String relNames = "";
1909 // if (nonNames.size() > 0){
1910 // nonRelNames += " [";
1912 // for (NameRelationship relName: nonNames){
1913 // String label = "non ";
1914 // TaxonName relatedName = null;
1915 // if (relName.getFromName().equals(name)){
1916 // relatedName = relName.getToName();
1917 // if (state.getConfig().isAddHTML()){
1918 // nonRelNames += label + createNameWithItalics(relatedName.getTaggedName())+ " ";
1920 // nonRelNames += label + relatedName.getTitleCache();
1924 //// label = relName.getType().getInverseLabel() + " ";
1925 //// relatedName = relName.getFromName();
1926 //// nonRelNames += label + relatedName.getTitleCache() + " ";
1929 // nonRelNames.trim();
1930 // if (nonNames.size() > 0){
1931 // nonRelNames = StringUtils.strip(nonRelNames, null);
1932 // nonRelNames += "] ";
1935 // //other relationships
1936 // if (otherRelationships.size() > 0){
1937 // relNames += " [";
1939 // for (NameRelationship rel: otherRelationships){
1940 // String label = "";
1941 // TaxonName relatedName = null;
1942 // if (rel.getFromName().equals(name)){
1943 // label = rel.getType().getLabel() + " ";
1944 // relatedName = rel.getToName();
1945 // if (state.getConfig().isAddHTML()){
1946 // relNames += label + createNameWithItalics(relatedName.getTaggedName())+ " ";
1948 // relNames += label + relatedName.getTitleCache();
1952 // label = rel.getType().getInverseLabel() + " ";
1953 // relatedName = rel.getFromName();
1954 // if (state.getConfig().isAddHTML()){
1955 // relNames += label + createNameWithItalics(relatedName.getTaggedName())+ " ";
1957 // relNames += label + relatedName.getTitleCache();
1962 // if (otherRelationships.size() > 0){
1963 // relNames = StringUtils.stripEnd(relNames, null);
1964 // relNames += "] ";
1968 // String synonymSign = "";
1970 // if (name.isInvalid()){
1971 // synonymSign = "\u2212 ";
1973 // synonymSign = "\u2261 ";
1976 // if (name.isInvalid() ){
1977 // synonymSign = "\u2212 ";
1979 // synonymSign = "\u003D ";
1982 // boolean isAccepted = false;
1984 // if (taxonBases.size() == 1){
1985 // taxonBase = HibernateProxyHelper.deproxy(taxonBases.iterator().next());
1987 // if (taxonBase.getSec() != null){
1988 // sec = OriginalSourceFormatter.INSTANCE_WITH_YEAR_BRACKETS.format(taxonBase.getSecSource());
1990 // if (taxonBase.isDoubtful()){
1995 // if (taxonBase instanceof Synonym){
1996 // if (isNotBlank(sec)){
1997 // sec = " syn. sec. " + sec + " ";
2002 // typifiedNamesWithoutAccepted += synonymSign + doubtful + nameString + nonRelNames + relNames;
2003 // typifiedNamesWithoutAcceptedWithSec += synonymSign + doubtful + nameString + sec + nonRelNames + relNames;
2006 // if (!(((Taxon)taxonBase).isProparteSynonym() || ((Taxon)taxonBase).isMisapplication())){
2007 // isAccepted = true;
2009 // synonymSign = "\u003D ";
2013 // if (taxonBase.getAppendedPhrase() != null){
2014 // if (state.getConfig().isAddHTML()){
2015 // String taxonString = createNameWithItalics(taxonBase.getTaggedTitle()) ;
2016 // taxonString = taxonString.replace("sec "+sec, "");
2017 // String nameCacheWithItalics = createNameWithItalics(name.getTaggedName());
2018 // nameString = nameString.replace(nameCacheWithItalics, taxonString);
2022 // //there are names used more than once?
2023 // for (TaxonBase<?> tb: taxonBases){
2024 // if (tb.getSec() != null){
2025 // sec = OriginalSourceFormatter.INSTANCE_WITH_YEAR_BRACKETS.format(tb.getSecSource());
2027 // if (tb.isDoubtful()){
2032 // if (tb instanceof Synonym ){
2033 // if (!((Synonym)tb).getAcceptedTaxon().equals(acceptedTaxon)) {
2036 // if (StringUtils.isNotBlank(sec)){
2037 // sec = " syn. sec. " + sec + " ";
2045 // if (!(((Taxon)tb).isProparteSynonym() || ((Taxon)tb).isMisapplication())){
2046 // isAccepted = true;
2049 // synonymSign = "\u003D ";
2053 // if (!isAccepted){
2054 // typifiedNamesWithoutAccepted += synonymSign + doubtful + nameString + "; ";
2055 // typifiedNamesWithoutAcceptedWithSec += synonymSign + doubtful + nameString + sec;
2056 // typifiedNamesWithoutAcceptedWithSec = typifiedNamesWithoutAcceptedWithSec.trim() + "; ";
2059 // typifiedNamesString += synonymSign + doubtful + nameString + nonRelNames + relNames;
2060 // typifiedNamesWithSecString += synonymSign + doubtful + nameString + sec + nonRelNames + relNames;
2066 // state.getProcessor().put(table, String.valueOf(group.getId()), csvLine);
2067 } catch (Exception e
) {
2068 state
.getResult().addException(e
, "An unexpected error occurred when handling homotypic group "
2069 + cdmBaseStr(group
) + ": " + e
.getMessage());
2073 private void handleReference(ColDpExportState state
, String
[] csvLine
, ColDpExportTable table
,
2074 ISourceable
<?
> sourceable
) {
2076 String referenceID
= null;
2077 for (IOriginalSource osb
: sourceable
.getSources()) {
2078 if (osb
.getCitation() != null && osb
.getType().isPrimarySource()) {
2079 referenceID
= CdmUtils
.concat(";", getId(state
, osb
.getCitation()));
2080 handleReference(state
, osb
.getCitation());
2083 csvLine
[table
.getIndex(ColDpExportTable
.REFERENCE_ID
)] = referenceID
;
2086 private void handleReference(ColDpExportState state
, Reference reference
) {
2088 if (state
.getReferenceStore().contains(reference
.getUuid())) {
2092 state
.addReferenceToStore(reference
);
2093 ColDpExportTable table
= ColDpExportTable
.REFERENCE
;
2094 String
[] csvLine
= new String
[table
.getSize()];
2095 reference
= HibernateProxyHelper
.deproxy(reference
);
2097 // TODO 1 reference short citations correctly
2098 // String shortCitation = OriginalSourceFormatter.INSTANCE_WITH_YEAR_BRACKETS.format(reference, null); // Should be Author(year) like in Taxon.sec
2099 // csvLine[table.getIndex(ColDpExportTable.BIBLIO_SHORT_CITATION)] = shortCitation;
2101 csvLine
[table
.getIndex(ColDpExportTable
.ID
)] = getId(state
, reference
);
2104 handleAlternativeId(state
, csvLine
, table
, reference
);
2106 //TODO 9 reference sourceID
2107 csvLine
[table
.getIndex(ColDpExportTable
.SOURCE_ID
)] = null;
2110 csvLine
[table
.getIndex(ColDpExportTable
.REF_CITATION
)] = reference
.getCitation();
2113 csvLine
[table
.getIndex(ColDpExportTable
.TYPE
)] = state
.getTransformer().getCacheByReferenceType(reference
);
2116 if (reference
.getAuthorship() != null) {
2117 TeamOrPersonBase
<?
> author
= reference
.getAuthorship();
2118 //TODO 3 reference author formatting fine tuning
2119 csvLine
[table
.getIndex(ColDpExportTable
.REF_AUTHOR
)] = author
.getTitleCache();
2123 if (reference
.getEditor() != null) { //if in future this is not a String
2124 //TODO 3 reference editor formatting fine tuning, not yet relevant
2125 csvLine
[table
.getIndex(ColDpExportTable
.REF_AUTHOR
)] = reference
.getEditor();
2128 // TODO 1 reference get preferred title
2129 csvLine
[table
.getIndex(ColDpExportTable
.REF_TITLE
)] = reference
.isProtectedTitleCache()
2130 ? reference
.getTitleCache() : reference
.getTitle();
2131 // csvLine[table.getIndex(ColDpExportTable.ABBREV_REF_TITLE)] = reference.isProtectedAbbrevTitleCache()
2132 // ? reference.getAbbrevTitleCache() : reference.getAbbrevTitle();
2135 if (reference
.getInReference() != null && reference
.getInSeries() != reference
.getInReference()) {
2136 //TODO 2 reference exclude series as inRef
2137 Reference inRef
= reference
.getInReference();
2140 if (inRef
.getAuthorship() != null) {
2141 TeamOrPersonBase
<?
> containerAuthor
= inRef
.getAuthorship();
2142 //TODO 1 reference inRef-author formatting fine tuning
2143 csvLine
[table
.getIndex(ColDpExportTable
.REF_CONTAINER_AUTHOR
)] = containerAuthor
.getTitleCache();
2146 // TODO 1 reference get preferred inRef-title
2147 csvLine
[table
.getIndex(ColDpExportTable
.REF_CONTAINER_TITLE
)] = inRef
.isProtectedTitleCache()
2148 ? inRef
.getTitleCache() : inRef
.getTitle();
2149 // csvLine[table.getIndex(ColDpExportTable.ABBREV_REF_TITLE)] = inRef.isProtectedAbbrevTitleCache()
2150 // ? inRef.getAbbrevTitleCache() : inRef.getAbbrevTitle();
2154 //issued TODO 2 reference issued formatting
2155 csvLine
[table
.getIndex(ColDpExportTable
.REF_ISSUED
)] = reference
.getDatePublishedString();
2157 //accessed TODO 2 reference accessed also for source and formatting
2158 if (reference
.getAccessed() != null) {
2159 csvLine
[table
.getIndex(ColDpExportTable
.REF_ACCESSED
)] = reference
.getAccessed().toDate().toString();
2162 if (reference
.getInSeries() != null) {
2163 Reference series
= reference
.getInReference();
2166 if (series
.getEditor() != null) {
2167 // TeamOrPersonBase<?> containerAuthor = series.getAuthorship();
2168 //TODO 2 reference collection editor
2169 csvLine
[table
.getIndex(ColDpExportTable
.REF_COLLECTION_EDITOR
)] = series
.getEditor();
2172 // TODO 2 reference get preferred title
2174 csvLine
[table
.getIndex(ColDpExportTable
.REF_COLLECTION_TITLE
)] = series
.isProtectedTitleCache()
2175 ? series
.getTitleCache() : series
.getTitle();
2176 // csvLine[table.getIndex(ColDpExportTable.ABBREV_REF_TITLE)] = inRef.isProtectedAbbrevTitleCache()
2177 // ? inRef.getAbbrevTitleCache() : inRef.getAbbrevTitle();
2182 csvLine
[table
.getIndex(ColDpExportTable
.REF_VOLUME
)] = getVolume(reference
);
2184 //issue TODO 2 reference issue (we currently do not handle issues separately, but could be parsed in some cases
2185 csvLine
[table
.getIndex(ColDpExportTable
.REF_ISSUE
)] = null;
2188 csvLine
[table
.getIndex(ColDpExportTable
.REF_EDITION
)] = reference
.getEdition();
2191 csvLine
[table
.getIndex(ColDpExportTable
.REF_PAGE
)] = reference
.getPages();
2193 //publisher TODO 3 reference publisher2
2194 csvLine
[table
.getIndex(ColDpExportTable
.REF_PUBLISHER
)] = reference
.getPublisher();
2196 //publisherPlace TODO 3 reference publisherPlace2
2197 csvLine
[table
.getIndex(ColDpExportTable
.REF_PUBLISHER_PLACE
)] = reference
.getPlacePublished();
2199 //TODO 7 reference version does not exist yet in CDM
2200 csvLine
[table
.getIndex(ColDpExportTable
.REF_VERSION
)] = null; //reference.getVersion();
2203 csvLine
[table
.getIndex(ColDpExportTable
.REF_ISBN
)] = reference
.getIsbn();
2206 csvLine
[table
.getIndex(ColDpExportTable
.REF_ISSN
)] = reference
.getIssn();
2209 csvLine
[table
.getIndex(ColDpExportTable
.REF_DOI
)] = reference
.getDoiString();
2211 //TODO 2 reference link link (=> external link)
2212 // csvLine[table.getIndex(ColDpExportTable.LINK)] = null;
2213 if (reference
.getUri() != null) {
2214 csvLine
[table
.getIndex(ColDpExportTable
.LINK
)] = reference
.getUri().toString();
2217 csvLine
[table
.getIndex(ColDpExportTable
.REMARKS
)] = getRemarks(reference
);
2219 state
.getProcessor().put(table
, reference
, csvLine
);
2220 } catch (Exception e
) {
2221 e
.printStackTrace();
2222 state
.getResult().addException(e
, "An unexpected error occurred when handling reference "
2223 + cdmBaseStr(reference
) + ": " + e
.getMessage());
2227 //TODO 2 fullAuthorship - still needed?
2228 private String
createFullAuthorship(Reference reference
) {
2229 TeamOrPersonBase
<?
> authorship
= reference
.getAuthorship();
2230 String fullAuthorship
= "";
2231 if (authorship
== null) {
2234 authorship
= HibernateProxyHelper
.deproxy(authorship
);
2235 if (authorship
instanceof Person
) {
2236 fullAuthorship
= ((Person
) authorship
).getTitleCache();
2238 } else if (authorship
instanceof Team
) {
2240 Team authorTeam
= (Team
)authorship
;
2241 fullAuthorship
= authorTeam
.cacheStrategy().getTitleCache(authorTeam
);
2243 return fullAuthorship
;
2246 private String
extractMediaUris(Iterator
<MediaRepresentation
> it
) {
2248 String mediaUriString
= "";
2249 boolean first
= true;
2250 while (it
.hasNext()) {
2251 MediaRepresentation rep
= it
.next();
2252 List
<MediaRepresentationPart
> parts
= rep
.getParts();
2253 for (MediaRepresentationPart part
: parts
) {
2255 if (part
.getUri() != null) {
2256 mediaUriString
+= part
.getUri().toString();
2260 if (part
.getUri() != null) {
2261 mediaUriString
+= ", " + part
.getUri().toString();
2267 return mediaUriString
;
2270 private String
extractLinkUris(Iterator
<ExternalLink
> it
) {
2272 String linkUriString
= "";
2273 boolean first
= true;
2274 while (it
.hasNext()) {
2275 ExternalLink link
= it
.next();
2277 if (link
.getUri() != null) {
2278 linkUriString
+= link
.getUri().toString();
2282 if (link
.getUri() != null) {
2283 linkUriString
+= ", " + link
.getUri().toString();
2287 return linkUriString
;
2290 private String
createCollectorString(ColDpExportState state
, GatheringEvent gathering
, FieldUnit fieldUnit
) {
2292 String collectorString
= "";
2293 AgentBase
<?
> collectorA
= CdmBase
.deproxy(gathering
.getCollector());
2294 if (gathering
.getCollector() != null) {
2295 if (collectorA
instanceof TeamOrPersonBase
&& state
.getConfig().isHighLightPrimaryCollector()) {
2297 Person primaryCollector
= fieldUnit
.getPrimaryCollector();
2298 if (collectorA
instanceof Team
) {
2299 Team collectorTeam
= (Team
) collectorA
;
2300 boolean isFirst
= true;
2301 for (Person member
: collectorTeam
.getTeamMembers()) {
2303 collectorString
+= "; ";
2305 if (member
.equals(primaryCollector
)) {
2307 collectorString
+= "<b>" + member
.getTitleCache() + "</b>";
2309 collectorString
+= member
.getTitleCache();
2314 collectorString
= collectorA
.getTitleCache();
2317 return collectorString
;
2318 } catch (Exception e
) {
2319 state
.getResult().addException(e
, "An unexpected error occurred when creating collector string for "
2320 + cdmBaseStr(fieldUnit
) + ": " + e
.getMessage());
2327 * Returns a string representation of the {@link CdmBase cdmBase} object for
2330 private String
cdmBaseStr(CdmBase cdmBase
) {
2331 if (cdmBase
== null) {
2332 return "-no object available-";
2334 return cdmBase
.getClass().getSimpleName() + ": " + cdmBase
.getUuid();
2339 protected boolean doCheck(ColDpExportState state
) {
2344 protected boolean isIgnore(ColDpExportState state
) {