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 //homotypic group / synonyms
305 HomotypicalGroup homotypicGroup
= taxon
.getHomotypicGroup();
307 handleHomotypicalGroup(state
, homotypicGroup
, taxon
);
308 for (Synonym syn
: taxon
.getSynonymsInGroup(homotypicGroup
)) {
309 handleSynonym(state
, syn
, index
);
313 List
<HomotypicalGroup
> heterotypicHomotypicGroups
= taxon
.getHeterotypicSynonymyGroups();
314 for (HomotypicalGroup group
: heterotypicHomotypicGroups
){
315 handleHomotypicalGroup(state
, group
, taxon
);
316 for (Synonym syn
: taxon
.getSynonymsInGroup(group
)) {
317 handleSynonym(state
, syn
, index
);
322 //TODO 2 pro parte synonyms and misapplications
323 // //pro parte synonyms
325 // for (Taxon tax : taxon.getAllProParteSynonyms()) {
326 // handleProPartePartialMisapplied(state, tax, taxon, true, false, index);
331 // for (Taxon tax : taxon.getAllMisappliedNames()) {
332 // handleProPartePartialMisapplied(state, tax, taxon, false, true, index);
337 ColDpExportTable table
= ColDpExportTable
.TAXON
;
338 String
[] csvLine
= new String
[table
.getSize()];
340 csvLine
[table
.getIndex(ColDpExportTable
.ID
)] = getId(state
, taxon
);
343 handleAlternativeId(state
, csvLine
, table
, taxon
);
345 //TODO 9 sourceID //handled in referenceID
346 csvLine
[table
.getIndex(ColDpExportTable
.SOURCE_ID
)] = null;
348 Taxon parent
= (taxonNode
.getParent() == null) ?
null : taxonNode
.getParent().getTaxon();
349 csvLine
[table
.getIndex(ColDpExportTable
.TAX_PARENT_ID
)] = getId(state
, parent
);
353 //TODO 9 branchLength
354 csvLine
[table
.getIndex(ColDpExportTable
.TAX_BRANCH_LENGTH
)] = null;
357 csvLine
[table
.getIndex(ColDpExportTable
.TAX_NAME_ID
)] = getId(state
, name
);
360 csvLine
[table
.getIndex(ColDpExportTable
.TAX_NAMEPHRASE
)] = taxon
.getAppendedPhrase();
363 csvLine
[table
.getIndex(ColDpExportTable
.TAX_SEC_ID
)] = getId(state
, taxon
.getSec());
364 if (taxon
.getSec() != null
365 && (!state
.getReferenceStore().contains((taxon
.getSec().getUuid())))) {
366 handleReference(state
, taxon
.getSec());
370 //TODO 4 SCRUTINIZER ID
371 //TODO 4 SCRUTINIZER Date
373 //TODO 2 taxon provisional, still an open issue?
374 csvLine
[table
.getIndex(ColDpExportTable
.TAX_PROVISIONAL
)] = taxonNode
.isDoubtful() ?
"1" : "0";
377 handleReference(state
, csvLine
, table
, taxon
);
379 //TODO 3 taxon extinct
381 //TODO 7 taxon temporalRangeStart
382 csvLine
[table
.getIndex(ColDpExportTable
.TAX_TEMPORAL_RANGE_END
)] = null;
383 //TODO 7 taxon temporalRangeEnd
384 csvLine
[table
.getIndex(ColDpExportTable
.TAX_TEMPORAL_RANGE_END
)] = null;
386 //TODO 5 taxon environment
387 csvLine
[table
.getIndex(ColDpExportTable
.TAX_ENVIRONMENT
)] = null;
389 //TODO 6 taxon species, section, subgenus, genus, ... - can be null if parent ID is given
392 csvLine
[table
.getIndex(ColDpExportTable
.REMARKS
)] = getRemarks(taxon
);
394 //TODO 1 taxon only published
397 state
.getProcessor().put(table
, taxon
, csvLine
);
400 handleDescriptions(state
, taxon
);
403 handleMedia(state
, taxon
);
405 } catch (Exception e
) {
407 state
.getResult().addException(e
,
408 "An unexpected problem occurred when trying to export taxon with id " + taxon
.getId() + " " + taxon
.getTitleCache());
409 state
.getResult().setState(ExportResultState
.INCOMPLETE_WITH_ERROR
);
411 } catch (Exception e
) {
412 state
.getResult().addException(e
, "An unexpected error occurred when handling the taxon node of "
413 + cdmBaseStr(taxonNode
.getTaxon()) + ", titleCache:"+ taxonNode
.getTaxon().getTitleCache()+": " + e
.getMessage());
417 private void handleAlternativeId(ColDpExportState state
, String
[] csvLine
, ColDpExportTable table
, IdentifiableEntity
<?
> entity
) {
418 String alternativeIdStr
= null;
420 for (Identifier identifier
: entity
.getIdentifiers()) {
421 //TODO 4 alternativeID filter Identifiers
422 IdentifierType type
= identifier
.getType();
423 String prefix
= null;
424 String value
= identifier
.getIdentifier();
425 String url
= identifier
.getUrl();
427 //TODO 4 alternativeID handle other identifier types
428 if (type
.equals(IdentifierType
.IDENTIFIER_NAME_WFO())) {
430 value
= value
.replace("wfo-", "");
432 }else if (url
!= null && !url
.isEmpty() && isUrl(url
)) {
435 //TODO 4 alternativeID log failing identifier
437 alternativeIdStr
= CdmUtils
.concat(",", alternativeIdStr
, CdmUtils
.concat(":", prefix
, value
));
440 csvLine
[table
.getIndex(ColDpExportTable
.ALTERNATIVE_ID
)] = alternativeIdStr
;
443 private boolean isUrl(String url
) {
445 if (url
.startsWith("http")) {
449 } catch (Exception e
) {
450 //exception should return false
455 private void handleMedia(ColDpExportState state
, Taxon taxon
) {
456 Set
<Media
> mediaSet
= new HashSet
<>();
458 //TODO 3 media collect media form other places
460 //collect from taxon image gallery
461 Set
<?
extends DescriptionBase
<?
>> descriptions
= taxon
.getDescriptions();
462 for (DescriptionBase
<?
> description
: descriptions
){
463 for (DescriptionElementBase o
: description
.getElements()){
464 DescriptionElementBase el
= CdmBase
.deproxy(o
);
465 if (el
.getMedia().size() > 0){
466 for (Media media
: el
.getMedia()){
473 //handle single media
474 for (Media media
: mediaSet
) {
475 for (MediaRepresentation repr
: media
.getRepresentations()){
476 for (MediaRepresentationPart part
: repr
.getParts()){
477 handleMediaRepresentation(state
, taxon
, part
);
483 private void handleMediaRepresentation(ColDpExportState state
, Taxon taxon
, MediaRepresentationPart part
) {
484 if (part
== null || state
.getMediaStore().contains(part
.getUuid())) {
488 state
.addMediaToStore(part
);
489 ColDpExportTable table
= ColDpExportTable
.MEDIA
;
490 String
[] csvLine
= new String
[table
.getSize()];
491 part
= HibernateProxyHelper
.deproxy(part
);
493 csvLine
[table
.getIndex(ColDpExportTable
.TAXON_ID
)] = getId(state
, taxon
);
495 //TODO 9 media sourceID //handled in referenceID
496 csvLine
[table
.getIndex(ColDpExportTable
.SOURCE_ID
)] = null;
499 if (part
.getUri() != null) {
500 csvLine
[table
.getIndex(ColDpExportTable
.MEDIA_URL
)] = part
.getUri().toString();
503 //TODO 3 media type, still open?
504 csvLine
[table
.getIndex(ColDpExportTable
.TYPE
)] = part
.getMediaRepresentation().getMimeType();
506 //TODO 3 media format
507 csvLine
[table
.getIndex(ColDpExportTable
.MEDIA_FORMAT
)] = null;
509 Media media
= part
.getMediaRepresentation().getMedia();
512 csvLine
[table
.getIndex(ColDpExportTable
.MEDIA_TITLE
)] = getTitleCache(media
);
515 csvLine
[table
.getIndex(ColDpExportTable
.MEDIA_CREATED
)] = toIsoDate(media
.getMediaCreated());
517 //creator //TODO 3 media format creator
518 csvLine
[table
.getIndex(ColDpExportTable
.MEDIA_CREATOR
)] = getTitleCache(media
.getArtist());
520 //TODO 5 media license
521 csvLine
[table
.getIndex(ColDpExportTable
.MEDIA_LICENSE
)] = null;
524 csvLine
[table
.getIndex(ColDpExportTable
.LINK
)] = null;
526 state
.getProcessor().put(table
, part
, csvLine
);
529 private String
toIsoDate(TimePeriod mediaCreated
) {
530 //TODO 2 date, what if end or freetext exist?
531 Partial partial
= mediaCreated
.getStart();
532 if (partial
== null || !partial
.isSupported(DateTimeFieldType
.year())
533 || !partial
.isSupported(DateTimeFieldType
.monthOfYear()) && partial
.isSupported(DateTimeFieldType
.dayOfMonth())) {
534 //TODO 2 date, log warning, also if mediaCreated.getEnd() != null or so
537 DateTimeFormatter formatter
= new DateTimeFormatterBuilder()
538 .appendYear(4, 4).appendLiteral('-')
539 .appendMonthOfYear(2).appendLiteral('-')
542 return partial
.toString(formatter
);
547 * transforms the given date to an iso date
549 protected String
toIsoDate(DateTime dateTime
) {
550 if (dateTime
== null) {
553 DateTimeFormatter formatter
= new DateTimeFormatterBuilder()
554 .appendYear(4, 4).appendLiteral('-')
555 .appendMonthOfYear(2).appendLiteral('-')
558 return formatter
.print(dateTime
);
561 private void handleDescriptions(ColDpExportState state
, Taxon taxon
) {
562 if (!state
.getConfig().isDoFactualData()) {
565 String titleCache
= null;
567 taxon
= HibernateProxyHelper
.deproxy(taxon
);
568 titleCache
= taxon
.getTitleCache();
569 Set
<TaxonDescription
> descriptions
= taxon
.getDescriptions();
570 List
<DescriptionElementBase
> distributionFacts
= new ArrayList
<>();
571 List
<DescriptionElementBase
> taxonInteractionsFacts
= new ArrayList
<>();
572 List
<DescriptionElementBase
> commonNameFacts
= new ArrayList
<>();
573 for (TaxonDescription description
: descriptions
) {
574 if (description
.getElements() != null) {
575 for (DescriptionElementBase element
: description
.getElements()) {
576 element
= CdmBase
.deproxy(element
);
577 if (element
.getFeature().equals(Feature
.COMMON_NAME())) {
578 commonNameFacts
.add(element
);
579 } else if (element
.getFeature().equals(Feature
.DISTRIBUTION())) {
580 distributionFacts
.add(element
);
581 } else if (element
.getFeature().isSupportsTaxonInteraction()) {
582 taxonInteractionsFacts
.add(element
);
589 if (!commonNameFacts
.isEmpty()) {
590 handleCommonNameFacts(state
, taxon
, commonNameFacts
);
592 if (!distributionFacts
.isEmpty()) {
593 handleDistributionFacts(state
, taxon
, distributionFacts
);
595 if (!taxonInteractionsFacts
.isEmpty()) {
596 handleTaxonInteractionsFacts(state
, taxon
, taxonInteractionsFacts
);
598 } catch (Exception e
) {
599 state
.getResult().addException(e
, "An unexpected error occurred when handling description of "
600 + cdmBaseStr(taxon
) + (titleCache
!= null?
(" " +titleCache
) : "")+": " + e
.getMessage());
604 private String
getRemarks(AnnotatableEntity entity
) {
605 String remarks
= null;
606 for (Annotation a
: entity
.getAnnotations()) {
607 //TODO 3 handle other annotation types
608 if (AnnotationType
.EDITORIAL().equals(a
.getAnnotationType())
609 && CdmUtils
.isNotBlank(a
.getText())){
610 remarks
= CdmUtils
.concat(";", remarks
, a
.getText());
616 // private void handleMetaData(ColDpExportState state) {
617 // ColDpExportTable table = ColDpExportTable.METADATA;
618 // String[] csvLine = new String[table.getSize()];
619 //// csvLine[table.getIndex(CdmLightExportTable.INSTANCE_ID)] = state.getConfig().getInctanceId();
620 //// csvLine[table.getIndex(CdmLightExportTable.INSTANCE_NAME)] = state.getConfig().getInstanceName();
621 // csvLine[table.getIndex(ColDpExportTable.DATASET_BASE_URL)] = state.getConfig().getBase_url();
622 // csvLine[table.getIndex(ColDpExportTable.DATASET_CONTRIBUTOR)] = state.getConfig().getContributor();
623 // csvLine[table.getIndex(ColDpExportTable.DATASET_CREATOR)] = state.getConfig().getCreator();
624 // csvLine[table.getIndex(ColDpExportTable.DATASET_DESCRIPTION)] = state.getConfig().getDescription();
625 // csvLine[table.getIndex(ColDpExportTable.DATASET_DOWNLOAD_LINK)] = state.getConfig().getDataset_download_link();
626 // csvLine[table.getIndex(ColDpExportTable.DATASET_KEYWORDS)] = state.getConfig().getKeywords();
627 // csvLine[table.getIndex(ColDpExportTable.DATASET_LANDINGPAGE)] = state.getConfig().getDataSet_landing_page();
629 // csvLine[table.getIndex(ColDpExportTable.DATASET_LANGUAGE)] = state.getConfig().getLanguage() != null? state.getConfig().getLanguage().getLabel(): null;
630 // csvLine[table.getIndex(ColDpExportTable.DATASET_LICENCE)] = state.getConfig().getLicence();
631 // csvLine[table.getIndex(ColDpExportTable.DATASET_LOCATION)] = state.getConfig().getLocation();
632 // csvLine[table.getIndex(ColDpExportTable.DATASET_RECOMMENDED_CITATTION)] = state.getConfig().getRecommended_citation();
633 // csvLine[table.getIndex(ColDpExportTable.DATASET_TITLE)] = state.getConfig().getTitle();
634 // state.getProcessor().put(table, "", csvLine);
637 private void handleTaxonInteractionsFacts(ColDpExportState state
, CdmBase cdmBase
,
638 List
<DescriptionElementBase
> taxonInteractionsFacts
) {
640 ColDpExportTable table
= ColDpExportTable
.SPECIES_INTERACTION
;
641 String titleCache
= null;
642 if (cdmBase
instanceof TaxonBase
){
643 titleCache
= ((TaxonBase
)cdmBase
).getTitleCache();
645 for (DescriptionElementBase element
: taxonInteractionsFacts
) {
649 String
[] csvLine
= new String
[table
.getSize()];
651 // csvLine[table.getIndex(ColDpExportTable.TAXON_ID)] = getId(state, element);
652 handleSource(state
, element
, table
);
653 csvLine
[table
.getIndex(ColDpExportTable
.TAXON_ID
)] = getId(state
, cdmBase
);
654 csvLine
[table
.getIndex(ColDpExportTable
.REL_TAXON_TAXON_ID
)] = getId(state
,
655 ((TaxonInteraction
) element
).getTaxon2());
656 //TODO 5 taxon interaction Scentific name for species interaction
657 //TODO 2 taxon interaction, why does this handling from other remarks handling?
658 csvLine
[table
.getIndex(ColDpExportTable
.REMARKS
)] = createMultilanguageString(
659 ((TaxonInteraction
) element
).getDescription());
660 state
.getProcessor().put(table
, element
, csvLine
);
662 } catch (Exception e
) {
663 state
.getResult().addException(e
, "An unexpected error occurred when handling taxon interaction"
664 + cdmBaseStr(element
) + (titleCache
!= null?
(" " +titleCache
) : "")+ ": " + e
.getMessage());
669 private void handleSimpleMediaFact(ColDpExportState state
, Taxon taxon
, ColDpExportTable table
,
670 DescriptionElementBase element
) {
673 handleSource(state
, element
, ColDpExportTable
.MEDIA
);
675 if (element
instanceof TextData
) {
676 TextData textData
= (TextData
) element
;
677 csvLine
= new String
[table
.getSize()];
678 csvLine
[table
.getIndex(ColDpExportTable
.TAXON_ID
)] = getId(state
, taxon
);
680 String mediaUris
= "";
681 for (Media media
: textData
.getMedia()) {
682 String mediaString
= extractMediaUris(media
.getRepresentations().iterator());
683 if (!StringUtils
.isBlank(mediaString
)) {
684 mediaUris
+= mediaString
+ ";";
686 state
.getResult().addWarning("Empty Media object for " + taxon
.getUserFriendlyTypeName() + " "
687 + taxon
.getUuid() + " (media: " + media
.getUuid() + ")");
690 csvLine
[table
.getIndex(ColDpExportTable
.MEDIA_URL
)] = mediaUris
;
691 //TODO 2 media title, type (MIME-type), what is meant here?
692 csvLine
[table
.getIndex(ColDpExportTable
.MEDIA_TITLE
)] = mediaUris
;
694 } catch (Exception e
) {
695 state
.getResult().addException(e
, "An unexpected error occurred when handling single simple fact "
696 + cdmBaseStr(element
) + ": " + e
.getMessage());
701 private String
createMultilanguageString(Map
<Language
, LanguageString
> multilanguageText
) {
703 int index
= multilanguageText
.size();
704 for (LanguageString langString
: multilanguageText
.values()) {
705 text
+= langString
.getText();
714 private String
createAnnotationsString(Set
<Annotation
> annotations
) {
715 StringBuffer strBuff
= new StringBuffer();
717 for (Annotation ann
: annotations
) {
718 if (ann
.getAnnotationType() == null || !ann
.getAnnotationType().equals(AnnotationType
.TECHNICAL())) {
719 strBuff
.append(ann
.getText());
720 strBuff
.append("; ");
724 if (strBuff
.length() > 2) {
725 return strBuff
.substring(0, strBuff
.length() - 2);
731 private void handleSource(ColDpExportState state
, DescriptionElementBase element
,
732 ColDpExportTable factsTable
) {
733 // ColDpExportTable table = ColDpExportTable.FACT_SOURCES;
735 // Set<DescriptionElementSource> sources = element.getSources();
737 // for (DescriptionElementSource source : sources) {
738 // if (!(source.getType().equals(OriginalSourceType.Import)
739 // && state.getConfig().isExcludeImportSources())) {
740 // String[] csvLine = new String[table.getSize()];
741 // Reference ref = source.getCitation();
742 // if ((ref == null) && (source.getNameUsedInSource() == null)) {
745 // if (ref != null) {
746 // if (!state.getReferenceStore().contains(ref.getUuid())) {
747 // handleReference(state, ref);
750 // csvLine[table.getIndex(ColDpExportTable.REFERENCE_FK)] = getId(state, ref);
752 // csvLine[table.getIndex(ColDpExportTable.FACT_FK)] = getId(state, element);
754 // csvLine[table.getIndex(ColDpExportTable.NAME_IN_SOURCE_FK)] = getId(state,
755 // source.getNameUsedInSource());
756 // csvLine[table.getIndex(ColDpExportTable.FACT_TYPE)] = factsTable.getTableName();
757 // if (StringUtils.isBlank(csvLine[table.getIndex(ColDpExportTable.REFERENCE_FK)])
758 // && StringUtils.isBlank(csvLine[table.getIndex(ColDpExportTable.NAME_IN_SOURCE_FK)])) {
761 // state.getProcessor().put(table, source, csvLine);
764 // } catch (Exception e) {
765 // state.getResult().addException(e, "An unexpected error occurred when handling single source "
766 // + cdmBaseStr(element) + ": " + e.getMessage());
770 private void handleDistributionFacts(ColDpExportState state
, Taxon taxon
,
771 List
<DescriptionElementBase
> distributionFacts
) {
773 ColDpExportTable table
= ColDpExportTable
.DISTRIBUTION
;
774 Set
<Distribution
> distributions
= new HashSet
<>();
775 for (DescriptionElementBase element
: distributionFacts
) {
777 //TODO 3 distribution also check feature
778 if (element
instanceof Distribution
) {
779 String
[] csvLine
= new String
[table
.getSize()];
780 Distribution distribution
= (Distribution
) element
;
781 distributions
.add(distribution
);
783 csvLine
[table
.getIndex(ColDpExportTable
.TAXON_ID
)] = getId(state
, taxon
);
785 NamedArea area
= CdmBase
.deproxy(distribution
.getArea());
787 String gazetteer
= "text";
788 String areaID
= null;
789 if (area
.getClass().equals(Country
.class)) {
790 Country country
= CdmBase
.deproxy(area
, Country
.class);
791 areaID
= country
.getIdInVocabulary();
793 } else if (NamedArea
.isTdwgArea(area
)) {
795 areaID
= area
.getIdInVocabulary();
799 csvLine
[table
.getIndex(ColDpExportTable
.DIST_AREA_ID
)] = areaID
;
802 //TODO 3 distribution area, does this always use the full English? Looks like this is not true for countries.
803 csvLine
[table
.getIndex(ColDpExportTable
.DIST_AREA
)] = area
.getLabel();
806 csvLine
[table
.getIndex(ColDpExportTable
.DIST_GAZETTEER
)] = gazetteer
;
809 if (distribution
.getStatus() != null) {
810 csvLine
[table
.getIndex(ColDpExportTable
.DIST_STATUS
)]
811 = state
.getTransformer().getCacheByPresenceAbsenceTerm(distribution
.getStatus());
815 handleReference(state
, csvLine
, table
, distribution
);
818 csvLine
[table
.getIndex(ColDpExportTable
.REMARKS
)] = getRemarks(distribution
);
820 state
.getProcessor().put(table
, distribution
, csvLine
);
823 .addError("The distribution description for the taxon " + taxon
.getUuid()
824 + " is not of type distribution. Could not be exported. UUID of the description element: "
825 + element
.getUuid());
827 } catch (Exception e
) {
829 state
.getResult().addException(e
, "An unexpected error occurred when handling single distribution "
830 + cdmBaseStr(element
) + ": " + e
.getMessage());
835 private void handleCommonNameFacts(ColDpExportState state
, Taxon taxon
,
836 List
<DescriptionElementBase
> commonNameFacts
) {
837 ColDpExportTable table
= ColDpExportTable
.VERNACULAR_NAME
;
839 for (DescriptionElementBase element
: commonNameFacts
) {
841 if (element
instanceof CommonTaxonName
) {
842 String
[] csvLine
= new String
[table
.getSize()];
843 CommonTaxonName commonName
= (CommonTaxonName
) element
;
844 csvLine
[table
.getIndex(ColDpExportTable
.TAXON_ID
)] = getId(state
, taxon
);
845 if (commonName
.getName() != null) {
846 csvLine
[table
.getIndex(ColDpExportTable
.VERN_NAME
)] = commonName
.getName();
849 //transliteration - we do not have this yet
850 csvLine
[table
.getIndex(ColDpExportTable
.VERN_TRANSLITERATION
)] = commonName
.getTransliteration();
852 if (commonName
.getLanguage() != null) {
853 //TODO 2 common name char(3) lang
854 csvLine
[table
.getIndex(ColDpExportTable
.VERN_LANGUAGE
)] = commonName
.getLanguage().getIso639_2();
857 //TODO 2 common name country
859 if (commonName
.getArea() != null) {
860 csvLine
[table
.getIndex(ColDpExportTable
.VERN_AREA
)] = commonName
.getArea().getLabel();
863 //sex - we do not have this yet
864 csvLine
[table
.getIndex(ColDpExportTable
.VERN_SEX
)] = null;
867 handleReference(state
, csvLine
, table
, commonName
);
869 state
.getProcessor().put(table
, commonName
, csvLine
);
870 } else if (element
instanceof TextData
){
871 String
[] csvLine
= new String
[table
.getSize()];
872 TextData commonName
= (TextData
) element
;
873 handleSource(state
, element
, table
);
874 csvLine
[table
.getIndex(ColDpExportTable
.TAXON_ID
)] = getId(state
, taxon
);
875 if (commonName
.getMultilanguageText() != null) {
876 csvLine
[table
.getIndex(ColDpExportTable
.VERN_NAME
)] = createMultilanguageString(commonName
.getMultilanguageText());
878 state
.getProcessor().put(table
, commonName
, csvLine
);
881 .addError("The common name description for the taxon " + taxon
.getUuid()
882 + " is not of type common name. Could not be exported. UUID of the description element: "
883 + element
.getUuid());
885 } catch (Exception e
) {
886 state
.getResult().addException(e
, "An unexpected error occurred when handling single common name "
887 + cdmBaseStr(element
) + " - "+taxon
.getTitleCache()+ ": " + e
.getMessage());
892 private String
getTitleCache(IIdentifiableEntity identEntity
) {
893 if (identEntity
== null) {
896 // TODO 3 titleCache refresh?
897 return identEntity
.getTitleCache();
900 private String
getId(ColDpExportState state
, ICdmBase cdmBase
) {
901 if (cdmBase
== null) {
904 // TODO 4 id type, make configurable
905 return cdmBase
.getUuid().toString();
908 private void handleSynonym(ColDpExportState state
, Synonym synonym
, int index
) {
910 if (isUnpublished(state
.getConfig(), synonym
)) {
913 TaxonName name
= synonym
.getName();
914 handleName(state
, name
, synonym
.getAcceptedTaxon());
916 ColDpExportTable table
= ColDpExportTable
.SYNONYM
;
917 String
[] csvLine
= new String
[table
.getSize()];
919 csvLine
[table
.getIndex(ColDpExportTable
.ID
)] = getId(state
, synonym
);
921 //TODO 9 synonym sourceID //handled in referenceID and sec_ID
922 csvLine
[table
.getIndex(ColDpExportTable
.SOURCE_ID
)] = null;
924 csvLine
[table
.getIndex(ColDpExportTable
.TAXON_ID
)] = getId(state
, synonym
.getAcceptedTaxon());
925 csvLine
[table
.getIndex(ColDpExportTable
.TAX_NAME_ID
)] = getId(state
, name
);
926 if (synonym
.getSec() != null && !state
.getReferenceStore().contains(synonym
.getSec().getUuid())) {
927 handleReference(state
, synonym
.getSec());
928 csvLine
[table
.getIndex(ColDpExportTable
.REFERENCE_ID
)] = getId(state
, synonym
.getSec());
930 csvLine
[table
.getIndex(ColDpExportTable
.TAX_NAMEPHRASE
)] = synonym
.getAppendedPhrase();
931 csvLine
[table
.getIndex(ColDpExportTable
.TAX_SEC_ID
)] = getId(state
, synonym
.getSec());
933 state
.getProcessor().put(table
, synonym
, csvLine
);
934 } catch (Exception e
) {
935 state
.getResult().addException(e
, "An unexpected error occurred when handling synonym "
936 + cdmBaseStr(synonym
) + ": " + e
.getMessage());
941 // * Handles misapplied names (including pro parte and partial as well as pro
942 // * parte and partial synonyms
944 // private void handleProPartePartialMisapplied(ColDpExportState state, Taxon taxon, Taxon accepted, boolean isProParte, boolean isMisapplied, int index) {
946 // Taxon ppSyonym = taxon;
947 // if (isUnpublished(state.getConfig(), ppSyonym)) {
950 // TaxonName name = ppSyonym.getName();
951 // handleName(state, name, accepted);
953 // ColDpExportTable table = ColDpExportTable.SYNONYM;
954 // String[] csvLine = new String[table.getSize()];
956 // csvLine[table.getIndex(ColDpExportTable.SYNONYM_ID)] = getId(state, ppSyonym);
957 // csvLine[table.getIndex(ColDpExportTable.TAXON_FK)] = getId(state, accepted);
958 // csvLine[table.getIndex(ColDpExportTable.NAME_FK)] = getId(state, name);
960 // Reference secRef = ppSyonym.getSec();
962 // if (secRef != null && !state.getReferenceStore().contains(secRef.getUuid())) {
963 // handleReference(state, secRef);
965 // csvLine[table.getIndex(ColDpExportTable.SEC_REFERENCE_FK)] = getId(state, secRef);
966 // csvLine[table.getIndex(ColDpExportTable.SEC_REFERENCE)] = getTitleCache(secRef);
967 // Set<TaxonRelationship> rels = accepted.getTaxonRelations(ppSyonym);
968 // TaxonRelationship rel = null;
969 // boolean isPartial = false;
970 // if (rels.size() == 1){
971 // rel = rels.iterator().next();
973 // }else if (rels.size() > 1){
974 // Iterator<TaxonRelationship> iterator = rels.iterator();
975 // while (iterator.hasNext()){
976 // rel = iterator.next();
977 // if (isProParte && rel.getType().isAnySynonym()){
979 // } else if (isMisapplied && rel.getType().isAnyMisappliedName()){
987 // Reference synSecRef = rel.getCitation();
988 // if (synSecRef != null && !state.getReferenceStore().contains(synSecRef.getUuid())) {
989 // handleReference(state, synSecRef);
991 // csvLine[table.getIndex(ColDpExportTable.SYN_SEC_REFERENCE_FK)] = getId(state, synSecRef);
992 // csvLine[table.getIndex(ColDpExportTable.SYN_SEC_REFERENCE)] = getTitleCache(synSecRef);
993 // isProParte = rel.getType().isProParte();
994 // isPartial = rel.getType().isPartial();
997 // state.getResult().addWarning("An unexpected error occurred when handling "
998 // + "pro parte/partial synonym or misapplied name " + cdmBaseStr(taxon) );
1001 // // pro parte type
1003 // csvLine[table.getIndex(ColDpExportTable.IS_PRO_PARTE)] = isProParte ? "1" : "0";
1004 // csvLine[table.getIndex(ColDpExportTable.IS_PARTIAL)] = isPartial ? "1" : "0";
1005 // csvLine[table.getIndex(ColDpExportTable.IS_MISAPPLIED)] = isMisapplied ? "1" : "0";
1006 // csvLine[table.getIndex(ColDpExportTable.SORT_INDEX)] = String.valueOf(index);
1007 // state.getProcessor().put(table, ppSyonym, csvLine);
1008 // } catch (Exception e) {
1009 // state.getResult().addException(e, "An unexpected error occurred when handling "
1010 // + "pro parte/partial synonym or misapplied name " + cdmBaseStr(taxon) + ": " + e.getMessage());
1014 private void handleName(ColDpExportState state
, TaxonName name
, Taxon acceptedTaxon
){
1015 handleName(state
, name
, acceptedTaxon
, false);
1018 private void handleName(ColDpExportState state
, TaxonName name
, Taxon acceptedTaxon
, boolean acceptedName
) {
1019 if (name
== null || state
.getNameStore().containsKey(name
.getId())) {
1023 ColDpExportTable table
= ColDpExportTable
.NAME
;
1024 String
[] csvLine
= new String
[table
.getSize()];
1026 Rank rank
= name
.getRank();
1027 name
= HibernateProxyHelper
.deproxy(name
);
1028 state
.getNameStore().put(name
.getId(), name
.getUuid());
1030 csvLine
[table
.getIndex(ColDpExportTable
.ID
)] = getId(state
, name
);
1032 //TODO 3 name, handle LSIDs
1033 // if (name.getLsid() != null) {
1034 // csvLine[table.getIndex(ColDpExportTable.LSID)] = name.getLsid().getLsid();
1036 // csvLine[table.getIndex(ColDpExportTable.LSID)] = "";
1038 handleAlternativeId(state
, csvLine
, table
, name
);
1040 //TODO 9 name sourceID
1041 csvLine
[table
.getIndex(ColDpExportTable
.SOURCE_ID
)] = null;
1044 TaxonName basionym
= name
.getBasionym(); //TODO 5 basionym, order in case there are >1 basionyms
1045 if (basionym
!= null) {
1046 if (!state
.getNameStore().containsKey(basionym
.getId())) {
1047 handleName(state
, basionym
, null);
1049 csvLine
[table
.getIndex(ColDpExportTable
.NAME_BASIONYM_ID
)] = getId(state
, basionym
);
1053 if (name
.isProtectedTitleCache() && StringUtils
.isEmpty(name
.getNameCache())) {
1054 //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
1055 String message
= "";
1056 if (StringUtils
.isEmpty(name
.getNameCache())) {
1057 csvLine
[table
.getIndex(ColDpExportTable
.NAME_SCIENTIFIC_NAME
)] = name
.getNameCache();
1058 message
= "ScientificName: Name cache " + name
.getNameCache() + " used for name with protected titleCache " + name
.getTitleCache();
1060 csvLine
[table
.getIndex(ColDpExportTable
.NAME_SCIENTIFIC_NAME
)] = name
.getTitleCache();
1061 message
= "ScientificName: Name has protected titleCache and no explicit nameCache: " + name
.getTitleCache();
1063 state
.getResult().addWarning(message
); //TODO 7 add location to warning
1065 csvLine
[table
.getIndex(ColDpExportTable
.NAME_SCIENTIFIC_NAME
)] = name
.getNameCache();
1069 csvLine
[table
.getIndex(ColDpExportTable
.NAME_AUTHORSHIP
)] = name
.getAuthorshipCache();
1070 //combinationAuthorship
1071 csvLine
[table
.getIndex(ColDpExportTable
.NAME_COMBINATION_AUTHORSHIP
)] = teamToString(name
.getCombinationAuthorship());
1072 //combinationExAuthorship
1073 csvLine
[table
.getIndex(ColDpExportTable
.NAME_COMBINATION_EX_AUTHORSHIP
)] = teamToString(name
.getExCombinationAuthorship());
1074 //combinationAuthorshipYear
1075 csvLine
[table
.getIndex(ColDpExportTable
.NAME_COMBINATION_AUTHORSHIP_YEAR
)] = name
.getNomenclaturalReference() == null ?
null : name
.getNomenclaturalReference().getYear();
1076 //basionymAuthorship
1077 csvLine
[table
.getIndex(ColDpExportTable
.NAME_BASIONYM_AUTHORSHIP
)] = teamToString(name
.getBasionymAuthorship());
1078 //basionymExAuthorship
1079 csvLine
[table
.getIndex(ColDpExportTable
.NAME_BASIONYM_EX_AUTHORSHIP
)] = teamToString(name
.getExBasionymAuthorship());
1080 //basionymAuthorshipYear
1081 csvLine
[table
.getIndex(ColDpExportTable
.NAME_BASIONYM_AUTHORSHIP_YEAR
)] =
1082 basionym
== null?
null :
1083 basionym
.getNomenclaturalReference() == null ?
null :
1084 basionym
.getNomenclaturalReference().getYear();
1087 csvLine
[table
.getIndex(ColDpExportTable
.RANK
)] = state
.getTransformer().getCacheByRank(rank
);
1090 if (name
.isGenusOrSupraGeneric()) {
1091 csvLine
[table
.getIndex(ColDpExportTable
.NAME_UNINOMIAL
)] = name
.getGenusOrUninomial();
1093 csvLine
[table
.getIndex(ColDpExportTable
.NAME_GENUS
)] = name
.getGenusOrUninomial();
1096 csvLine
[table
.getIndex(ColDpExportTable
.NAME_INFRAGENERIC_EPITHET
)] = name
.getInfraGenericEpithet();
1097 csvLine
[table
.getIndex(ColDpExportTable
.NAME_SPECIFIC_EPITHET
)] = name
.getSpecificEpithet();
1098 csvLine
[table
.getIndex(ColDpExportTable
.NAME_INFRASPECIFIC_EPITHET
)] = name
.getInfraSpecificEpithet();
1100 //TODO 3 name cultivar epithet, group epithet
1101 csvLine
[table
.getIndex(ColDpExportTable
.NAME_CULTIVAR_EPITHET
)] = name
.getCultivarEpithet();
1104 csvLine
[table
.getIndex(ColDpExportTable
.NAME_CODE
)] = state
.getTransformer().getCacheByNomenclaturalCode(name
.getNameType());
1106 //TODO 5 name status, is this handling correct?
1107 //Also according to documentation we should put more detailed status information to the remarks field
1108 // or an URI from the NOMEN ontology could be used
1109 if (name
.getStatus() == null || name
.getStatus().isEmpty()) {
1110 csvLine
[table
.getIndex(ColDpExportTable
.NAME_STATUS
)] = "acceptable";
1112 NomenclaturalStatus status
= name
.getStatus().iterator().next();
1113 if (name
.getStatus().size() > 1) {
1114 String message
= "There is >1 name status for " + name
.getTitleCache();
1115 state
.getResult().addWarning(message
);
1117 String statusTypeString
= state
.getTransformer().getCacheByNomStatus(status
.getType());
1118 csvLine
[table
.getIndex(ColDpExportTable
.NAME_STATUS
)] = statusTypeString
;
1119 if (statusTypeString
== null) {
1120 String message
= "Name status " + status
.getType() + " not yet handled for name " + name
.getTitleCache();
1121 state
.getResult().addWarning(message
);
1126 Reference nomRef
= name
.getNomenclaturalReference();
1127 if (nomRef
!= null) {
1128 csvLine
[table
.getIndex(ColDpExportTable
.REFERENCE_ID
)] = getId(state
, nomRef
);
1129 handleReference(state
, nomRef
);
1132 if (nomRef
.getDatePublished() != null) {
1133 csvLine
[table
.getIndex(ColDpExportTable
.NAME_PUBLISHED_IN_YEAR
)] = nomRef
.getDatePublished().getYear();
1135 nomRef
= HibernateProxyHelper
.deproxy(nomRef
);
1136 if (nomRef
.getInReference() != null) {
1137 Reference inReference
= nomRef
.getInReference();
1138 if (inReference
.getDatePublished() != null && nomRef
.getDatePublished() == null) {
1139 csvLine
[table
.getIndex(ColDpExportTable
.NAME_PUBLISHED_IN_YEAR
)]
1140 = inReference
.getDatePublished().getYear();
1146 if (name
.getNomenclaturalMicroReference() != null) {
1147 csvLine
[table
.getIndex(ColDpExportTable
.NAME_PUBLISHED_IN_PAGE
)] = name
.getNomenclaturalMicroReference();
1150 //publishedInPageLink
1151 String protologueUriString
= extractProtologueURIs(state
, name
);
1152 csvLine
[table
.getIndex(ColDpExportTable
.NAME_PUBLISHED_IN_PAGE_LINK
)] = protologueUriString
;
1154 //TODO 2 name links - do we have this in CDM?
1157 csvLine
[table
.getIndex(ColDpExportTable
.REMARKS
)] = getRemarks(name
);
1159 handleTypeMaterial(state
, name
);
1162 state
.getProcessor().put(table
, name
, csvLine
);
1163 //TODO 1 nameRelationships - is this still an open issue? Do tests exist?
1164 handleNameRelationships(state
, name
);
1166 } catch (Exception e
) {
1167 state
.getResult().addException(e
,
1168 "An unexpected error occurred when handling the name " + cdmBaseStr(name
) + ": " + name
.getTitleCache() + ": " + e
.getMessage());
1170 e
.printStackTrace();
1174 private String
teamToString(TeamOrPersonBase
<?
> author
) {
1175 if (author
== null) {
1178 String nomCache
= author
.getNomenclaturalTitleCache();
1179 if (StringUtils
.isEmpty(nomCache
)){
1185 .replace(" & ", "|")
1187 .replace(" et ", "|");
1191 private void handleTypeMaterial(ColDpExportState state
, TaxonName name
) {
1193 ColDpExportTable table
= ColDpExportTable
.TYPE_MATERIAL
;
1194 String
[] csvLine
= new String
[table
.getSize()];
1196 Collection
<TypeDesignationBase
> specimenTypeDesignations
= new ArrayList
<>();
1197 List
<TextualTypeDesignation
> textualTypeDesignations
= new ArrayList
<>();
1199 for (TypeDesignationBase
<?
> typeDesignation
: name
.getTypeDesignations()) {
1200 if (typeDesignation
.isInstanceOf(TextualTypeDesignation
.class)) {
1201 if (((TextualTypeDesignation
) typeDesignation
).isVerbatim() ){
1202 Set
<IdentifiableSource
> sources
= typeDesignation
.getSources();
1203 boolean isProtologue
= false;
1204 if (sources
!= null && !sources
.isEmpty()){
1205 IdentifiableSource source
= sources
.iterator().next();
1206 if (name
.getNomenclaturalReference() != null){
1207 isProtologue
= source
.getCitation() != null? source
.getCitation().getUuid().equals(name
.getNomenclaturalReference().getUuid()): false;
1211 csvLine
[table
.getIndex(ColDpExportTable
.TYPE_CITATION
)] = ((TextualTypeDesignation
) typeDesignation
)
1212 .getPreferredText(Language
.DEFAULT());
1214 //TODO 2 specimen type textual type designation, still open?
1215 textualTypeDesignations
.add((TextualTypeDesignation
) typeDesignation
);
1218 ///TODO 2 specimen type textual type designation, still open?
1219 textualTypeDesignations
.add((TextualTypeDesignation
) typeDesignation
);
1221 } else if (typeDesignation
.isInstanceOf(SpecimenTypeDesignation
.class)) {
1222 SpecimenTypeDesignation specimenType
= HibernateProxyHelper
.deproxy(typeDesignation
, SpecimenTypeDesignation
.class);
1223 specimenTypeDesignations
.add(specimenType
);
1224 handleSpecimenType(state
, specimenType
, csvLine
, table
, name
);
1225 }else if (typeDesignation
instanceof NameTypeDesignation
){
1227 // specimenTypeDesignations.add(HibernateProxyHelper.deproxy(typeDesignation, NameTypeDesignation.class));
1231 TypeDesignationSetContainer typeContainer
= new TypeDesignationSetContainer(specimenTypeDesignations
, name
, TypeDesignationSetComparator
.ORDER_BY
.TYPE_STATUS
);
1232 HTMLTagRules rules
= new HTMLTagRules();
1233 //rules.addRule(TagEnum.name, "i");
1234 csvLine
[table
.getIndex(ColDpExportTable
.TYPE_CITATION
)] = typeContainer
.print(false, false, false, rules
);
1236 //TODO 2 type material what is this second type computation? Is it only about sources?
1237 StringBuilder stringbuilder
= new StringBuilder();
1239 for (TextualTypeDesignation typeDesignation
: textualTypeDesignations
) {
1240 stringbuilder
.append(typeDesignation
.getPreferredText(Language
.DEFAULT()));
1241 if (typeDesignation
.getSources() != null && !typeDesignation
.getSources().isEmpty() ){
1242 stringbuilder
.append( " [");
1244 for (IdentifiableSource source
: typeDesignation
.getSources()){
1245 if (source
.getCitation() != null){
1246 stringbuilder
.append(OriginalSourceFormatter
.INSTANCE
.format(source
));
1248 if (index
< typeDesignation
.getSources().size()) {
1249 stringbuilder
.append( ", ");
1253 stringbuilder
.append( "]");
1255 if (i
< textualTypeDesignations
.size()) {
1256 stringbuilder
.append( "; ");
1258 stringbuilder
.append(".");
1262 csvLine
[table
.getIndex(ColDpExportTable
.TYPE_CITATION
)] = stringbuilder
.toString();
1263 } catch (Exception e
) {
1264 state
.getResult().addException(e
,
1265 "An unexpected error occurred when handling the type designations for name " + cdmBaseStr(name
) + ": " + name
.getTitleCache() + ": " + e
.getMessage());
1266 e
.printStackTrace();
1270 //TODO 2 specimen type what is the difference to handleSpecimenType()
1271 // private void handleSpecimenType_(ColDpExportState state, SpecimenTypeDesignation specimenType) {
1273 // if (specimenType.getTypeSpecimen() != null){
1274 // DerivedUnit specimen = specimenType.getTypeSpecimen();
1275 // if(specimen != null && !state.getSpecimenStore().contains( specimen.getUuid())){
1276 // handleSpecimen(state, specimen);
1280 // String[] csvLine = new String[table.getSize()];
1281 // //TYPE_ID, SPECIMEN_FK, TYPE_VERBATIM_CITATION, TYPE_STATUS, TYPE_DESIGNATED_BY_STRING, TYPE_DESIGNATED_BY_REF_FK};
1282 // //Specimen_Fk und den Typusangaben (Art des Typus [holo, lecto, etc.], Quelle, Designation-Quelle, +
1283 // Set<TaxonName> typifiedNames = specimenType.getTypifiedNames();
1284 // for (TaxonName name: typifiedNames){
1285 // csvLine[table.getIndex(ColDpExportTable.TYPE_STATUS)] = specimenType.getTypeStatus() != null? specimenType.getTypeStatus().getDescription(): "";
1286 // csvLine[table.getIndex(ColDpExportTable.TYPE_ID)] = getId(state, specimenType);
1287 // csvLine[table.getIndex(ColDpExportTable.TYPIFIED_NAME_FK)] = getId(state, name);
1288 // csvLine[table.getIndex(ColDpExportTable.SPECIMEN_FK)] = getId(state, specimenType.getTypeSpecimen());
1289 // if (specimenType.getSources() != null && !specimenType.getSources().isEmpty()){
1290 // String sourceString = "";
1292 // for (IdentifiableSource source: specimenType.getSources()){
1293 // if (source.getCitation()!= null){
1294 // sourceString = sourceString.concat(source.getCitation().getCitation());
1297 // if (index != specimenType.getSources().size()){
1298 // sourceString.concat(", ");
1301 // csvLine[table.getIndex(ColDpExportTable.TYPE_INFORMATION_REF_STRING)] = sourceString;
1303 // if (specimenType.getDesignationSource() != null && specimenType.getDesignationSource().getCitation() != null && !state.getReferenceStore().contains(specimenType.getDesignationSource().getCitation().getUuid())){
1304 // handleReference(state, specimenType.getDesignationSource().getCitation());
1305 // csvLine[table.getIndex(ColDpExportTable.TYPE_DESIGNATED_BY_REF_FK)] = specimenType.getDesignationSource() != null ? getId(state, specimenType.getDesignationSource().getCitation()): "";
1308 // state.getProcessor().put(table, specimenType, csvLine);
1312 private void handleSpecimenType(ColDpExportState state
, SpecimenTypeDesignation specimenType
, String
[] csvLine
, ColDpExportTable table
, TaxonName name
) {
1316 DerivedUnit specimen
= specimenType
.getTypeSpecimen();
1317 if (specimenType
.getTypeSpecimen() == null){
1319 //handleSpecimen(state, specimen);
1322 //ID - TODO 3 specimen type best use dwc:occurrenceID
1323 csvLine
[table
.getIndex(ColDpExportTable
.ID
)] = getId(state
, specimen
);
1325 //TODO 9 specimenType sourceID //handled in referenceID
1326 csvLine
[table
.getIndex(ColDpExportTable
.SOURCE_ID
)] = null;
1329 Set
<TaxonName
> typifiedNames
= specimenType
.getTypifiedNames();
1330 if (typifiedNames
.size() > 1){
1331 //TODO 3 specimen type we should
1332 state
.getResult().addWarning("Please check the specimen type "
1333 + cdmBaseStr(specimenType
) + " there are more then one typified name.");
1335 // if (typifiedNames.iterator().hasNext()){
1336 // TaxonName name = typifiedNames.iterator().next();
1337 csvLine
[table
.getIndex(ColDpExportTable
.TYPE_NAMEID
)] = getId(state
, name
);
1340 //TODO 3 specimen type citation - also done in calling method
1341 csvLine
[table
.getIndex(ColDpExportTable
.TYPE_CITATION
)] = specimen
.getTitleCache();
1344 //TODO 3 specimen type type status transformation
1345 csvLine
[table
.getIndex(ColDpExportTable
.TYPE_STATUS
)] = specimenType
.getTypeStatus() != null? specimenType
.getTypeStatus().getDescription(): "";
1347 //TODO 2 specimen type referenceID - see description, should be designation ref id or original name refid
1348 if (specimenType
.getDesignationSource() != null && specimenType
.getDesignationSource().getCitation() != null && !state
.getReferenceStore().contains(specimenType
.getDesignationSource().getCitation().getUuid())){
1349 //TODO 3 specimen type, should be source, not reference; why?
1350 handleReference(state
, specimenType
.getDesignationSource().getCitation());
1351 csvLine
[table
.getIndex(ColDpExportTable
.REFERENCE_ID
)] = specimenType
.getDesignationSource() != null ?
getId(state
, specimenType
.getDesignationSource().getCitation()): "";
1355 if (specimen
.getCollection() != null) {
1356 //TODO 3 specimen type institution code not available handling
1357 csvLine
[table
.getIndex(ColDpExportTable
.TYPE_INSTITUTION_CODE
)] = specimen
.getCollection().getCode();
1361 if (specimen
.isInstanceOf(DerivedUnit
.class)){
1362 DerivedUnit derivedUnit
= specimen
;
1363 String catalogNumber
= null;
1364 if (!StringUtils
.isBlank(derivedUnit
.getBarcode())){
1365 catalogNumber
= derivedUnit
.getBarcode();
1366 } else if (!StringUtils
.isBlank(derivedUnit
.getAccessionNumber())){
1367 catalogNumber
= derivedUnit
.getAccessionNumber();
1368 } else if (!StringUtils
.isBlank(derivedUnit
.getCatalogNumber())){
1369 catalogNumber
= derivedUnit
.getCatalogNumber();
1371 csvLine
[table
.getIndex(ColDpExportTable
.TYPE_CATALOG_NUMBER
)] = catalogNumber
;
1374 //TODO 9 specimen type associatedSequences - not yet implemented
1375 csvLine
[table
.getIndex(ColDpExportTable
.TYPE_ASSOC_SEQ
)] = null;
1378 if (specimen
.getSex() != null) {
1379 //TODO 7 specimen type transform sex, we usually don't have specimen with sex
1380 csvLine
[table
.getIndex(ColDpExportTable
.TYPE_SEX
)] = specimen
.getSex().getLabel();
1384 if (specimen
.getPreferredStableUri() != null) {
1385 csvLine
[table
.getIndex(ColDpExportTable
.LINK
)] = specimen
.getPreferredStableUri().toString();
1389 //TODO 3 specimen type gather remarks on type designation, field unit(s) and specimen
1390 csvLine
[table
.getIndex(ColDpExportTable
.REMARKS
)] = getRemarks(specimen
);
1393 //TODO 3 specimen type performance due to service call
1394 Collection
<FieldUnit
> fieldUnits
= this.getOccurrenceService().findFieldUnits(specimen
.getUuid(), null);
1395 if (!fieldUnits
.isEmpty()) {
1396 if (fieldUnits
.size() > 1) {
1397 state
.getResult().addWarning("There are >1 field units for specimen "
1398 + cdmBaseStr(specimen
) + ".");
1401 FieldUnit fieldUnit
= fieldUnits
.iterator().next();
1403 GatheringEvent gathering
= fieldUnit
.getGatheringEvent();
1404 if (gathering
!= null) {
1405 handleGatheringEvent(state
, csvLine
, table
, fieldUnit
, gathering
);
1409 state
.getProcessor().put(table
, specimenType
, csvLine
);
1410 }catch (Exception e
) {
1411 state
.getResult().addException(e
,
1412 "An unexpected error occurred when handling type material for name " + cdmBaseStr(name
) + ": " + name
.getTitleCache() + ": " + e
.getMessage());
1413 e
.printStackTrace();
1417 private void handleGatheringEvent(ColDpExportState state
, String
[] csvLine
, ColDpExportTable table
,
1418 FieldUnit fieldUnit
, GatheringEvent gathering
) {
1420 if (gathering
.getLocality() != null) {
1421 csvLine
[table
.getIndex(ColDpExportTable
.TYPE_LOCALITY
)]
1422 = gathering
.getLocality().getText();
1424 //TODO 3 gathering include areas, see CDM-light implementation and COL-DP description
1427 if (gathering
.getCountry() != null) {
1428 csvLine
[table
.getIndex(ColDpExportTable
.TYPE_COUNTRY
)]
1429 = gathering
.getCountry().getLabel();
1433 Point point
= gathering
.getExactLocation();
1434 if (point
!= null) {
1436 if (point
.getLatitude() != null) {
1437 //TODO 3 gathering rounding
1438 csvLine
[table
.getIndex(ColDpExportTable
.TYPE_LATITUDE
)]
1439 = point
.getLatitude().toString();
1442 if (point
.getLongitude() != null) {
1443 //TODO 3 gathering rounding
1444 csvLine
[table
.getIndex(ColDpExportTable
.TYPE_LONGITUDE
)]
1445 = point
.getLongitude().toString();
1450 if (gathering
.getAbsoluteElevation() != null) {
1451 //TODO 3 type specimen include max/text/depth
1452 csvLine
[table
.getIndex(ColDpExportTable
.TYPE_ALTITUDE
)]
1453 = gathering
.getAbsoluteElevation().toString();
1456 //host - does more or less not exist in CDM
1457 csvLine
[table
.getIndex(ColDpExportTable
.TYPE_HOST
)] = null;
1460 if (gathering
.getGatheringDate() != null) {
1461 //TODO 3 specimen type ISO 8601
1462 csvLine
[table
.getIndex(ColDpExportTable
.TYPE_DATE
)] = gathering
1463 .getGatheringDate().toString();
1467 csvLine
[table
.getIndex(ColDpExportTable
.TYPE_COLLECTOR
)]
1468 = createCollectorString(state
, gathering
, fieldUnit
);
1469 //field number not yet in COL-DP
1470 //csvLine[table.getIndex(ColDpExportTable.COLLECTOR_NUMBER)] = fieldUnit.getFieldNumber();
1473 private String
createNameWithItalics(List
<TaggedText
> taggedName
) {
1475 String fullTitleWithHtml
= "";
1476 for (TaggedText taggedText
: taggedName
){
1477 if (taggedText
.getType().equals(TagEnum
.name
)){
1478 fullTitleWithHtml
+= "<i>" + taggedText
.getText() + "</i> ";
1479 }else if (taggedText
.getType().equals(TagEnum
.separator
)){
1480 fullTitleWithHtml
= fullTitleWithHtml
.trim() + taggedText
.getText() ;
1482 fullTitleWithHtml
+= taggedText
.getText() + " ";
1485 return fullTitleWithHtml
;
1488 private void handleNameRelationships(ColDpExportState state
, TaxonName name
) {
1489 ColDpExportTable table
= ColDpExportTable
.NAME_RELATION
;
1490 ColDpExportTransformer transformer
= (ColDpExportTransformer
)state
.getTransformer();
1492 //relations in which "name" is the from name
1493 Set
<NameRelationship
> fromRels
= name
.getRelationsFromThisName();
1494 for (NameRelationship rel
: fromRels
) {
1495 ColDpNameRelType coldpType
= transformer
.getColDpNameRelTypeByNameRelationType(rel
.getType());
1496 if (coldpType
== null) {
1497 handleNoColDpNameRelType(state
, rel
.getType(), name
);
1499 }else if (coldpType
.getDirection() == 0) {
1500 continue; //the relation is handled the other way round if necessary
1503 TaxonName name2
= CdmBase
.deproxy(rel
.getToName());
1504 handleRelNameCommonData(state
, table
, rel
, name
, name2
, coldpType
);
1507 //relations in which "name" is the toName
1508 Set
<NameRelationship
> toRels
= name
.getRelationsToThisName();
1509 for (NameRelationship rel
: toRels
) {
1510 ColDpNameRelType coldpType
= transformer
.getColDpNameRelTypeByNameRelationType(rel
.getType());
1511 if (coldpType
== null) {
1512 handleNoColDpNameRelType(state
, rel
.getType(), name
);
1514 }else if (coldpType
.getDirection() == 1) {
1515 continue; //the relation is handled the other way round if necessary
1518 TaxonName name2
= CdmBase
.deproxy(rel
.getFromName());
1519 handleRelNameCommonData(state
, table
, rel
, name
, name2
, coldpType
);
1521 } catch (Exception e
) {
1522 state
.getResult().addException(e
,
1523 "An unexpected error occurred when handling name relationships for name "
1524 + cdmBaseStr(name
) + ": " + name
.getTitleCache() + ": " + e
.getMessage());
1525 e
.printStackTrace();
1529 private void handleNoColDpNameRelType(ColDpExportState state
, NameRelationshipType nameRelType
, TaxonName taxonName
) {
1531 if (nameRelType
== null) {
1532 warning
= "Name relationship has not type for name " + taxonName
.getTitleCache();
1534 //TODO misspelling, alternative name, blocking name for, avoids homonym of, unspecific "non"
1535 warning
= "Name relationship type not yet handled by COL-DP: " + nameRelType
.getTitleCache() + "; name: " + taxonName
.getTitleCache();
1537 state
.getResult().addWarning(warning
);
1540 private void handleRelNameCommonData(ColDpExportState state
, ColDpExportTable table
,
1541 NameRelationship rel
, TaxonName name
, TaxonName relatedName
, ColDpNameRelType coldpType
) {
1543 String
[] csvLine
= new String
[table
.getSize()];
1545 if (!state
.getNameStore().containsKey(relatedName
.getId())) {
1546 handleName(state
, relatedName
, null);
1548 csvLine
[table
.getIndex(ColDpExportTable
.REL_NAME_NAMEID
)] = getId(state
, name
);
1549 csvLine
[table
.getIndex(ColDpExportTable
.REL_NAME_REL_NAMEID
)] = getId(state
, relatedName
);
1551 csvLine
[table
.getIndex(ColDpExportTable
.TYPE
)] = coldpType
.getLabel();
1552 csvLine
[table
.getIndex(ColDpExportTable
.SOURCE_ID
)] = null;
1553 if (rel
.getCitation() != null) {
1554 handleReference(state
, rel
.getCitation());
1555 csvLine
[table
.getIndex(ColDpExportTable
.REFERENCE_ID
)] = getId(state
, rel
.getCitation());
1558 csvLine
[table
.getIndex(ColDpExportTable
.REMARKS
)] = getRemarks(rel
);
1559 state
.getProcessor().put(table
, rel
.getUuid().toString(), csvLine
);
1562 private String
getVolume(Reference reference
) {
1563 if (reference
.getVolume() != null) {
1564 return reference
.getVolume();
1565 } else if (reference
.getInReference() != null) {
1566 if (reference
.getInReference().getVolume() != null) {
1567 return reference
.getInReference().getVolume();
1573 // private void handleIdentifier(ColDpExportState state, CdmBase cdmBase) {
1574 // ColDpExportTable table = ColDpExportTable.IDENTIFIER;
1575 // String[] csvLine;
1577 // if (cdmBase instanceof TaxonName){
1578 // TaxonName name = (TaxonName)cdmBase;
1581 // List<Identifier> identifiers = name.getIdentifiers();
1583 // //first check which kind of identifiers are available and then sort and create table entries
1584 // Map<IdentifierType, Set<Identifier>> identifierTypes = new HashMap<>();
1585 // for (Identifier identifier: identifiers){
1586 // IdentifierType type = identifier.getType();
1587 // if (identifierTypes.containsKey(type)){
1588 // identifierTypes.get(type).add(identifier);
1590 // Set<Identifier> tempList = new HashSet<>();
1591 // tempList.add(identifier);
1592 // identifierTypes.put(type, tempList);
1596 // for (IdentifierType type:identifierTypes.keySet()){
1597 // Set<Identifier> identifiersByType = identifierTypes.get(type);
1598 // csvLine = new String[table.getSize()];
1599 // csvLine[table.getIndex(ColDpExportTable.FK)] = getId(state, name);
1600 // csvLine[table.getIndex(ColDpExportTable.REF_TABLE)] = "ScientificName";
1601 // csvLine[table.getIndex(ColDpExportTable.IDENTIFIER_TYPE)] = type.getLabel();
1602 // csvLine[table.getIndex(ColDpExportTable.EXTERNAL_NAME_IDENTIFIER)] = extractIdentifier(
1603 // identifiersByType);
1604 // state.getProcessor().put(table, name.getUuid() + ", " + type.getLabel(), csvLine);
1608 //// Set<String> IPNIidentifiers = name.getIdentifiers(DefinedTerm.IDENTIFIER_NAME_IPNI());
1609 //// Set<String> tropicosIdentifiers = name.getIdentifiers(DefinedTerm.IDENTIFIER_NAME_TROPICOS());
1610 //// Set<String> WFOIdentifiers = name.getIdentifiers(DefinedTerm.uuidWfoNameIdentifier);
1611 //// if (!IPNIidentifiers.isEmpty()) {
1612 //// csvLine = new String[table.getSize()];
1613 //// csvLine[table.getIndex(CdmLightExportTable.FK)] = getId(state, name);
1614 //// csvLine[table.getIndex(CdmLightExportTable.REF_TABLE)] = "ScientificName";
1615 //// csvLine[table.getIndex(CdmLightExportTable.IDENTIFIER_TYPE)] = IPNI_NAME_IDENTIFIER;
1616 //// csvLine[table.getIndex(CdmLightExportTable.EXTERNAL_NAME_IDENTIFIER)] = extractIdentifier(
1617 //// IPNIidentifiers);
1618 //// state.getProcessor().put(table, name.getUuid() + ", " + IPNI_NAME_IDENTIFIER, csvLine);
1620 //// if (!tropicosIdentifiers.isEmpty()) {
1621 //// csvLine = new String[table.getSize()];
1622 //// csvLine[table.getIndex(CdmLightExportTable.FK)] = getId(state, name);
1623 //// csvLine[table.getIndex(CdmLightExportTable.REF_TABLE)] = "ScientificName";
1624 //// csvLine[table.getIndex(CdmLightExportTable.IDENTIFIER_TYPE)] = TROPICOS_NAME_IDENTIFIER;
1625 //// csvLine[table.getIndex(CdmLightExportTable.EXTERNAL_NAME_IDENTIFIER)] = extractIdentifier(
1626 //// tropicosIdentifiers);
1627 //// state.getProcessor().put(table, name.getUuid() + ", " + IPNI_NAME_IDENTIFIER, csvLine);
1629 //// if (!WFOIdentifiers.isEmpty()) {
1630 //// csvLine = new String[table.getSize()];
1631 //// csvLine[table.getIndex(CdmLightExportTable.FK)] = getId(state, name);
1632 //// csvLine[table.getIndex(CdmLightExportTable.REF_TABLE)] = "ScientificName";
1633 //// csvLine[table.getIndex(CdmLightExportTable.IDENTIFIER_TYPE)] = WFO_NAME_IDENTIFIER;
1634 //// csvLine[table.getIndex(CdmLightExportTable.EXTERNAL_NAME_IDENTIFIER)] = extractIdentifier(
1635 //// WFOIdentifiers);
1636 //// state.getProcessor().put(table, name.getUuid() + ", " + WFO_NAME_IDENTIFIER, csvLine);
1638 // }catch(Exception e){
1639 // state.getResult().addWarning("Please check the identifiers for "
1640 // + cdmBaseStr(cdmBase) + " maybe there is an empty identifier");
1645 // if (cdmBase instanceof IdentifiableEntity){
1646 // IdentifiableEntity<?> identifiableEntity = (IdentifiableEntity<?>) cdmBase;
1647 // List<Identifier> identifiers = identifiableEntity.getIdentifiers();
1648 // String tableName = null;
1649 // if (cdmBase instanceof Reference){
1650 // tableName = "Reference";
1651 // }else if (cdmBase instanceof SpecimenOrObservationBase){
1652 // tableName = "Specimen";
1653 // }else if (cdmBase instanceof Taxon){
1654 // tableName = "Taxon";
1655 // }else if (cdmBase instanceof Synonym){
1656 // tableName = "Synonym";
1657 // }else if (cdmBase instanceof TeamOrPersonBase){
1658 // tableName = "PersonOrTeam";
1661 // for (Identifier identifier: identifiers){
1662 // if (identifier.getType() == null && identifier.getIdentifier() == null){
1663 // state.getResult().addWarning("Please check the identifiers for "
1664 // + cdmBaseStr(cdmBase) + " there is an empty identifier");
1668 // csvLine = new String[table.getSize()];
1669 // csvLine[table.getIndex(ColDpExportTable.FK)] = getId(state, cdmBase);
1671 // if (tableName != null){
1672 // csvLine[table.getIndex(ColDpExportTable.REF_TABLE)] = tableName;
1673 // csvLine[table.getIndex(ColDpExportTable.IDENTIFIER_TYPE)] = identifier.getType() != null? identifier.getType().getLabel():null;
1674 // csvLine[table.getIndex(ColDpExportTable.EXTERNAL_NAME_IDENTIFIER)] = identifier.getIdentifier();
1675 // state.getProcessor().put(table, cdmBase.getUuid() + (identifier.getType() != null? identifier.getType().getLabel():null), csvLine);
1678 // if (cdmBase instanceof Reference ){
1679 // Reference ref = (Reference)cdmBase;
1680 // if (ref.getDoi() != null){
1681 // csvLine = new String[table.getSize()];
1682 // csvLine[table.getIndex(ColDpExportTable.FK)] = getId(state, cdmBase);
1683 // csvLine[table.getIndex(ColDpExportTable.REF_TABLE)] = tableName;
1684 // csvLine[table.getIndex(ColDpExportTable.IDENTIFIER_TYPE)] = "DOI";
1685 // csvLine[table.getIndex(ColDpExportTable.EXTERNAL_NAME_IDENTIFIER)] = ref.getDoiString();
1686 // state.getProcessor().put(table, cdmBase.getUuid() + "DOI", csvLine);
1690 // if (cdmBase instanceof TeamOrPersonBase){
1691 // TeamOrPersonBase<?> person= HibernateProxyHelper.deproxy(cdmBase, TeamOrPersonBase.class);
1692 // if (person instanceof Person && ((Person)person).getOrcid() != 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)] = "ORCID";
1697 // csvLine[table.getIndex(ColDpExportTable.EXTERNAL_NAME_IDENTIFIER)]= ((Person)person).getOrcid().asURI();
1698 // state.getProcessor().put(table, cdmBase.getUuid() + "ORCID", csvLine);
1703 // } catch (Exception e) {
1704 // state.getResult().addException(e, "An unexpected error occurred when handling identifiers for "
1705 // + cdmBaseStr(cdmBase) + ": " + e.getMessage());
1706 // e.printStackTrace();
1710 // private String extractIdentifier(Set<Identifier> identifierSet) {
1712 // String identifierString = "";
1713 // for (Identifier identifier : identifierSet) {
1714 // if (!StringUtils.isBlank(identifierString)) {
1715 // identifierString += ", ";
1717 // identifierString += identifier.getIdentifier();
1719 // return identifierString;
1722 private String
extractProtologueURIs(ColDpExportState state
, TaxonName name
) {
1723 if (name
.getNomenclaturalSource() != null){
1724 Set
<ExternalLink
> links
= name
.getNomenclaturalSource().getLinks();
1725 return extractLinkUris(links
.iterator());
1731 private String
extractMediaURIs(ColDpExportState state
, Set
<?
extends DescriptionBase
<?
>> descriptionsSet
,
1734 String mediaUriString
= "";
1735 Set
<DescriptionElementBase
> elements
= new HashSet
<>();
1736 for (DescriptionBase
<?
> description
: descriptionsSet
) {
1738 if (!description
.getElements().isEmpty()) {
1739 elements
= description
.getElements();
1741 for (DescriptionElementBase element
: elements
) {
1742 Feature entityFeature
= HibernateProxyHelper
.deproxy(element
.getFeature());
1743 if (entityFeature
.equals(feature
)) {
1744 if (!element
.getMedia().isEmpty()) {
1745 List
<Media
> media
= element
.getMedia();
1746 for (Media mediaElement
: media
) {
1747 Iterator
<MediaRepresentation
> it
= mediaElement
.getRepresentations().iterator();
1748 mediaUriString
= extractMediaUris(it
);
1754 } catch (Exception e
) {
1755 state
.getResult().addException(e
, "An unexpected error occurred when extracting media URIs for "
1756 + cdmBaseStr(description
) + ": " + e
.getMessage());
1759 return mediaUriString
;
1763 private String
extractStatusString(ColDpExportState state
, TaxonName name
, boolean abbrev
) {
1765 Set
<NomenclaturalStatus
> status
= name
.getStatus();
1766 if (status
.isEmpty()) {
1769 String statusString
= "";
1770 for (NomenclaturalStatus nameStatus
: status
) {
1771 if (nameStatus
!= null) {
1773 if (nameStatus
.getType() != null) {
1774 statusString
+= nameStatus
.getType().getIdInVocabulary();
1777 if (nameStatus
.getType() != null) {
1778 statusString
+= nameStatus
.getType().getTitleCache();
1783 if (nameStatus
.getRuleConsidered() != null
1784 && !StringUtils
.isBlank(nameStatus
.getRuleConsidered())) {
1785 statusString
+= ": " + nameStatus
.getRuleConsidered();
1787 if (nameStatus
.getCitation() != null) {
1788 String shortCitation
= OriginalSourceFormatter
.INSTANCE
.format(nameStatus
.getCitation(), null);
1789 statusString
+= " (" + shortCitation
+ ")";
1791 // if (nameStatus.getCitationMicroReference() != null
1792 // && !StringUtils.isBlank(nameStatus.getCitationMicroReference())) {
1793 // statusString += " " + nameStatus.getCitationMicroReference();
1796 statusString
+= " ";
1799 return statusString
;
1800 } catch (Exception e
) {
1801 state
.getResult().addException(e
, "An unexpected error occurred when extracting status string for "
1802 + cdmBaseStr(name
) + ": " + e
.getMessage());
1807 private void handleHomotypicalGroup(ColDpExportState state
, HomotypicalGroup group
, Taxon acceptedTaxon
) {
1810 List
<TaxonName
> typifiedNames
= new ArrayList
<>();
1811 if (acceptedTaxon
!= null){
1812 List
<Synonym
> synonymsInGroup
= acceptedTaxon
.getSynonymsInGroup(group
);
1813 if (group
.equals(acceptedTaxon
.getHomotypicGroup())){
1814 typifiedNames
.add(acceptedTaxon
.getName());
1816 synonymsInGroup
.stream().forEach(synonym
-> typifiedNames
.add(CdmBase
.deproxy(synonym
.getName())));
1820 TaxonName firstname
= null;
1821 for (TaxonName name
: typifiedNames
){
1822 Iterator
<Taxon
> taxa
= name
.getTaxa().iterator();
1823 while(taxa
.hasNext()){
1824 Taxon taxon
= taxa
.next();
1825 if(!(taxon
.isMisapplication() || taxon
.isProparteSynonym())){
1832 //// Collections.sort(typifiedNames, new HomotypicalGroupNameComparator(firstname, true));
1833 // String typifiedNamesString = "";
1834 // String typifiedNamesWithSecString = "";
1835 // String typifiedNamesWithoutAccepted = "";
1836 // String typifiedNamesWithoutAcceptedWithSec = "";
1838 // for (TaxonName name : typifiedNames) {
1839 // // Concatenated output string for homotypic group (names and
1840 // // citations) + status + some name relations (e.g. “non”)
1841 // // TODO 3 commented code - can this be deleted? -- : nameRelations, which and how to display
1842 // Set<TaxonBase> taxonBases = name.getTaxonBases();
1843 // TaxonBase<?> taxonBase;
1846 // String nameString = name.getFullTitleCache();
1847 // String doubtful = "";
1849 // if (state.getConfig().isAddHTML()){
1850 // nameString = createNameWithItalics(name.getTaggedFullTitle()) ;
1853 // Set<NameRelationship> related = name.getNameRelations();
1854 // List<NameRelationship> relatedList = new ArrayList<>(related);
1856 // Collections.sort(relatedList, (nr1, nr2)-> {
1857 // return nr1.getType().compareTo(nr2.getType());});
1859 // List<NameRelationship> nonNames = new ArrayList<>();
1860 // List<NameRelationship> otherRelationships = new ArrayList<>();
1862 // for (NameRelationship rel: relatedList){
1863 // //no inverse relations
1864 // if (rel.getFromName().equals(name)){
1865 // // alle Homonyme und inverse blocking names
1866 // if (rel.getType().equals(NameRelationshipType.LATER_HOMONYM())
1867 // || rel.getType().equals(NameRelationshipType.TREATED_AS_LATER_HOMONYM())
1868 // || (rel.getType().equals(NameRelationshipType.BLOCKING_NAME_FOR()))
1869 // || (rel.getType().equals(NameRelationshipType.UNSPECIFIC_NON()))
1870 // || (rel.getType().equals(NameRelationshipType.AVOIDS_HOMONYM_OF()))
1872 // nonNames.add(rel);
1873 // }else if (!rel.getType().isBasionymRelation()){
1874 // otherRelationships.add(rel);
1877 // if (state.getConfig().isShowInverseNameRelationsInHomotypicGroup()) {
1878 // if (rel.getToName().equals(name)){
1879 // // alle Homonyme und inverse blocking names
1880 //// if (rel.getType().equals(NameRelationshipType.LATER_HOMONYM())
1881 //// || rel.getType().equals(NameRelationshipType.TREATED_AS_LATER_HOMONYM())
1882 //// || (rel.getType().equals(NameRelationshipType.BLOCKING_NAME_FOR()))
1883 //// || (rel.getType().equals(NameRelationshipType.UNSPECIFIC_NON()))
1884 //// || (rel.getType().equals(NameRelationshipType.AVOIDS_HOMONYM_OF()))
1886 //// nonNames.add(rel);
1887 //// }else if (!rel.getType().isBasionymRelation()){
1888 // otherRelationships.add(rel);
1894 // String nonRelNames = "";
1895 // String relNames = "";
1897 // if (nonNames.size() > 0){
1898 // nonRelNames += " [";
1900 // for (NameRelationship relName: nonNames){
1901 // String label = "non ";
1902 // TaxonName relatedName = null;
1903 // if (relName.getFromName().equals(name)){
1904 // relatedName = relName.getToName();
1905 // if (state.getConfig().isAddHTML()){
1906 // nonRelNames += label + createNameWithItalics(relatedName.getTaggedName())+ " ";
1908 // nonRelNames += label + relatedName.getTitleCache();
1912 //// label = relName.getType().getInverseLabel() + " ";
1913 //// relatedName = relName.getFromName();
1914 //// nonRelNames += label + relatedName.getTitleCache() + " ";
1917 // nonRelNames.trim();
1918 // if (nonNames.size() > 0){
1919 // nonRelNames = StringUtils.strip(nonRelNames, null);
1920 // nonRelNames += "] ";
1923 // //other relationships
1924 // if (otherRelationships.size() > 0){
1925 // relNames += " [";
1927 // for (NameRelationship rel: otherRelationships){
1928 // String label = "";
1929 // TaxonName relatedName = null;
1930 // if (rel.getFromName().equals(name)){
1931 // label = rel.getType().getLabel() + " ";
1932 // relatedName = rel.getToName();
1933 // if (state.getConfig().isAddHTML()){
1934 // relNames += label + createNameWithItalics(relatedName.getTaggedName())+ " ";
1936 // relNames += label + relatedName.getTitleCache();
1940 // label = rel.getType().getInverseLabel() + " ";
1941 // relatedName = rel.getFromName();
1942 // if (state.getConfig().isAddHTML()){
1943 // relNames += label + createNameWithItalics(relatedName.getTaggedName())+ " ";
1945 // relNames += label + relatedName.getTitleCache();
1950 // if (otherRelationships.size() > 0){
1951 // relNames = StringUtils.stripEnd(relNames, null);
1952 // relNames += "] ";
1956 // String synonymSign = "";
1958 // if (name.isInvalid()){
1959 // synonymSign = "\u2212 ";
1961 // synonymSign = "\u2261 ";
1964 // if (name.isInvalid() ){
1965 // synonymSign = "\u2212 ";
1967 // synonymSign = "\u003D ";
1970 // boolean isAccepted = false;
1972 // if (taxonBases.size() == 1){
1973 // taxonBase = HibernateProxyHelper.deproxy(taxonBases.iterator().next());
1975 // if (taxonBase.getSec() != null){
1976 // sec = OriginalSourceFormatter.INSTANCE_WITH_YEAR_BRACKETS.format(taxonBase.getSecSource());
1978 // if (taxonBase.isDoubtful()){
1983 // if (taxonBase instanceof Synonym){
1984 // if (isNotBlank(sec)){
1985 // sec = " syn. sec. " + sec + " ";
1990 // typifiedNamesWithoutAccepted += synonymSign + doubtful + nameString + nonRelNames + relNames;
1991 // typifiedNamesWithoutAcceptedWithSec += synonymSign + doubtful + nameString + sec + nonRelNames + relNames;
1994 // if (!(((Taxon)taxonBase).isProparteSynonym() || ((Taxon)taxonBase).isMisapplication())){
1995 // isAccepted = true;
1997 // synonymSign = "\u003D ";
2001 // if (taxonBase.getAppendedPhrase() != null){
2002 // if (state.getConfig().isAddHTML()){
2003 // String taxonString = createNameWithItalics(taxonBase.getTaggedTitle()) ;
2004 // taxonString = taxonString.replace("sec "+sec, "");
2005 // String nameCacheWithItalics = createNameWithItalics(name.getTaggedName());
2006 // nameString = nameString.replace(nameCacheWithItalics, taxonString);
2010 // //there are names used more than once?
2011 // for (TaxonBase<?> tb: taxonBases){
2012 // if (tb.getSec() != null){
2013 // sec = OriginalSourceFormatter.INSTANCE_WITH_YEAR_BRACKETS.format(tb.getSecSource());
2015 // if (tb.isDoubtful()){
2020 // if (tb instanceof Synonym ){
2021 // if (!((Synonym)tb).getAcceptedTaxon().equals(acceptedTaxon)) {
2024 // if (StringUtils.isNotBlank(sec)){
2025 // sec = " syn. sec. " + sec + " ";
2033 // if (!(((Taxon)tb).isProparteSynonym() || ((Taxon)tb).isMisapplication())){
2034 // isAccepted = true;
2037 // synonymSign = "\u003D ";
2041 // if (!isAccepted){
2042 // typifiedNamesWithoutAccepted += synonymSign + doubtful + nameString + "; ";
2043 // typifiedNamesWithoutAcceptedWithSec += synonymSign + doubtful + nameString + sec;
2044 // typifiedNamesWithoutAcceptedWithSec = typifiedNamesWithoutAcceptedWithSec.trim() + "; ";
2047 // typifiedNamesString += synonymSign + doubtful + nameString + nonRelNames + relNames;
2048 // typifiedNamesWithSecString += synonymSign + doubtful + nameString + sec + nonRelNames + relNames;
2054 // state.getProcessor().put(table, String.valueOf(group.getId()), csvLine);
2055 } catch (Exception e
) {
2056 state
.getResult().addException(e
, "An unexpected error occurred when handling homotypic group "
2057 + cdmBaseStr(group
) + ": " + e
.getMessage());
2061 private void handleReference(ColDpExportState state
, String
[] csvLine
, ColDpExportTable table
,
2062 ISourceable
<?
> sourceable
) {
2064 String referenceID
= null;
2065 for (IOriginalSource osb
: sourceable
.getSources()) {
2066 if (osb
.getCitation() != null && osb
.getType().isPrimarySource()) {
2067 referenceID
= CdmUtils
.concat(";", getId(state
, osb
.getCitation()));
2068 handleReference(state
, osb
.getCitation());
2071 csvLine
[table
.getIndex(ColDpExportTable
.REFERENCE_ID
)] = referenceID
;
2074 private void handleReference(ColDpExportState state
, Reference reference
) {
2076 if (state
.getReferenceStore().contains(reference
.getUuid())) {
2080 state
.addReferenceToStore(reference
);
2081 ColDpExportTable table
= ColDpExportTable
.REFERENCE
;
2082 String
[] csvLine
= new String
[table
.getSize()];
2083 reference
= HibernateProxyHelper
.deproxy(reference
);
2085 // TODO 1 reference short citations correctly
2086 // String shortCitation = OriginalSourceFormatter.INSTANCE_WITH_YEAR_BRACKETS.format(reference, null); // Should be Author(year) like in Taxon.sec
2087 // csvLine[table.getIndex(ColDpExportTable.BIBLIO_SHORT_CITATION)] = shortCitation;
2089 csvLine
[table
.getIndex(ColDpExportTable
.ID
)] = getId(state
, reference
);
2092 handleAlternativeId(state
, csvLine
, table
, reference
);
2094 //TODO 9 reference sourceID
2095 csvLine
[table
.getIndex(ColDpExportTable
.SOURCE_ID
)] = null;
2098 csvLine
[table
.getIndex(ColDpExportTable
.REF_CITATION
)] = reference
.getCitation();
2101 csvLine
[table
.getIndex(ColDpExportTable
.TYPE
)] = state
.getTransformer().getCacheByReferenceType(reference
);
2104 if (reference
.getAuthorship() != null) {
2105 TeamOrPersonBase
<?
> author
= reference
.getAuthorship();
2106 //TODO 3 reference author formatting fine tuning
2107 csvLine
[table
.getIndex(ColDpExportTable
.REF_AUTHOR
)] = author
.getTitleCache();
2111 if (reference
.getEditor() != null) { //if in future this is not a String
2112 //TODO 3 reference editor formatting fine tuning, not yet relevant
2113 csvLine
[table
.getIndex(ColDpExportTable
.REF_AUTHOR
)] = reference
.getEditor();
2116 // TODO 1 reference get preferred title
2117 csvLine
[table
.getIndex(ColDpExportTable
.REF_TITLE
)] = reference
.isProtectedTitleCache()
2118 ? reference
.getTitleCache() : reference
.getTitle();
2119 // csvLine[table.getIndex(ColDpExportTable.ABBREV_REF_TITLE)] = reference.isProtectedAbbrevTitleCache()
2120 // ? reference.getAbbrevTitleCache() : reference.getAbbrevTitle();
2123 if (reference
.getInReference() != null && reference
.getInSeries() != reference
.getInReference()) {
2124 //TODO 2 reference exclude series as inRef
2125 Reference inRef
= reference
.getInReference();
2128 if (inRef
.getAuthorship() != null) {
2129 TeamOrPersonBase
<?
> containerAuthor
= inRef
.getAuthorship();
2130 //TODO 1 reference inRef-author formatting fine tuning
2131 csvLine
[table
.getIndex(ColDpExportTable
.REF_CONTAINER_AUTHOR
)] = containerAuthor
.getTitleCache();
2134 // TODO 1 reference get preferred inRef-title
2135 csvLine
[table
.getIndex(ColDpExportTable
.REF_CONTAINER_TITLE
)] = inRef
.isProtectedTitleCache()
2136 ? inRef
.getTitleCache() : inRef
.getTitle();
2137 // csvLine[table.getIndex(ColDpExportTable.ABBREV_REF_TITLE)] = inRef.isProtectedAbbrevTitleCache()
2138 // ? inRef.getAbbrevTitleCache() : inRef.getAbbrevTitle();
2142 //issued TODO 2 reference issued formatting
2143 csvLine
[table
.getIndex(ColDpExportTable
.REF_ISSUED
)] = reference
.getDatePublishedString();
2145 //accessed TODO 2 reference accessed also for source and formatting
2146 if (reference
.getAccessed() != null) {
2147 csvLine
[table
.getIndex(ColDpExportTable
.REF_ACCESSED
)] = reference
.getAccessed().toDate().toString();
2150 if (reference
.getInSeries() != null) {
2151 Reference series
= reference
.getInReference();
2154 if (series
.getEditor() != null) {
2155 // TeamOrPersonBase<?> containerAuthor = series.getAuthorship();
2156 //TODO 2 reference collection editor
2157 csvLine
[table
.getIndex(ColDpExportTable
.REF_COLLECTION_EDITOR
)] = series
.getEditor();
2160 // TODO 2 reference get preferred title
2162 csvLine
[table
.getIndex(ColDpExportTable
.REF_COLLECTION_TITLE
)] = series
.isProtectedTitleCache()
2163 ? series
.getTitleCache() : series
.getTitle();
2164 // csvLine[table.getIndex(ColDpExportTable.ABBREV_REF_TITLE)] = inRef.isProtectedAbbrevTitleCache()
2165 // ? inRef.getAbbrevTitleCache() : inRef.getAbbrevTitle();
2170 csvLine
[table
.getIndex(ColDpExportTable
.REF_VOLUME
)] = getVolume(reference
);
2172 //issue TODO 2 reference issue (we currently do not handle issues separately, but could be parsed in some cases
2173 csvLine
[table
.getIndex(ColDpExportTable
.REF_ISSUE
)] = null;
2176 csvLine
[table
.getIndex(ColDpExportTable
.REF_EDITION
)] = reference
.getEdition();
2179 csvLine
[table
.getIndex(ColDpExportTable
.REF_PAGE
)] = reference
.getPages();
2181 //publisher TODO 3 reference publisher2
2182 csvLine
[table
.getIndex(ColDpExportTable
.REF_PUBLISHER
)] = reference
.getPublisher();
2184 //publisherPlace TODO 3 reference publisherPlace2
2185 csvLine
[table
.getIndex(ColDpExportTable
.REF_PUBLISHER_PLACE
)] = reference
.getPlacePublished();
2187 //TODO 7 reference version does not exist yet in CDM
2188 csvLine
[table
.getIndex(ColDpExportTable
.REF_VERSION
)] = null; //reference.getVersion();
2191 csvLine
[table
.getIndex(ColDpExportTable
.REF_ISBN
)] = reference
.getIsbn();
2194 csvLine
[table
.getIndex(ColDpExportTable
.REF_ISSN
)] = reference
.getIssn();
2197 csvLine
[table
.getIndex(ColDpExportTable
.REF_DOI
)] = reference
.getDoiString();
2199 //TODO 2 reference link link (=> external link)
2200 // csvLine[table.getIndex(ColDpExportTable.LINK)] = null;
2201 if (reference
.getUri() != null) {
2202 csvLine
[table
.getIndex(ColDpExportTable
.LINK
)] = reference
.getUri().toString();
2205 csvLine
[table
.getIndex(ColDpExportTable
.REMARKS
)] = getRemarks(reference
);
2207 state
.getProcessor().put(table
, reference
, csvLine
);
2208 } catch (Exception e
) {
2209 e
.printStackTrace();
2210 state
.getResult().addException(e
, "An unexpected error occurred when handling reference "
2211 + cdmBaseStr(reference
) + ": " + e
.getMessage());
2215 //TODO 2 fullAuthorship - still needed?
2216 private String
createFullAuthorship(Reference reference
) {
2217 TeamOrPersonBase
<?
> authorship
= reference
.getAuthorship();
2218 String fullAuthorship
= "";
2219 if (authorship
== null) {
2222 authorship
= HibernateProxyHelper
.deproxy(authorship
);
2223 if (authorship
instanceof Person
) {
2224 fullAuthorship
= ((Person
) authorship
).getTitleCache();
2226 } else if (authorship
instanceof Team
) {
2228 Team authorTeam
= (Team
)authorship
;
2229 fullAuthorship
= authorTeam
.cacheStrategy().getTitleCache(authorTeam
);
2231 return fullAuthorship
;
2234 private String
extractMediaUris(Iterator
<MediaRepresentation
> it
) {
2236 String mediaUriString
= "";
2237 boolean first
= true;
2238 while (it
.hasNext()) {
2239 MediaRepresentation rep
= it
.next();
2240 List
<MediaRepresentationPart
> parts
= rep
.getParts();
2241 for (MediaRepresentationPart part
: parts
) {
2243 if (part
.getUri() != null) {
2244 mediaUriString
+= part
.getUri().toString();
2248 if (part
.getUri() != null) {
2249 mediaUriString
+= ", " + part
.getUri().toString();
2255 return mediaUriString
;
2258 private String
extractLinkUris(Iterator
<ExternalLink
> it
) {
2260 String linkUriString
= "";
2261 boolean first
= true;
2262 while (it
.hasNext()) {
2263 ExternalLink link
= it
.next();
2265 if (link
.getUri() != null) {
2266 linkUriString
+= link
.getUri().toString();
2270 if (link
.getUri() != null) {
2271 linkUriString
+= ", " + link
.getUri().toString();
2275 return linkUriString
;
2278 private String
createCollectorString(ColDpExportState state
, GatheringEvent gathering
, FieldUnit fieldUnit
) {
2280 String collectorString
= "";
2281 AgentBase
<?
> collectorA
= CdmBase
.deproxy(gathering
.getCollector());
2282 if (gathering
.getCollector() != null) {
2283 if (collectorA
instanceof TeamOrPersonBase
&& state
.getConfig().isHighLightPrimaryCollector()) {
2285 Person primaryCollector
= fieldUnit
.getPrimaryCollector();
2286 if (collectorA
instanceof Team
) {
2287 Team collectorTeam
= (Team
) collectorA
;
2288 boolean isFirst
= true;
2289 for (Person member
: collectorTeam
.getTeamMembers()) {
2291 collectorString
+= "; ";
2293 if (member
.equals(primaryCollector
)) {
2295 collectorString
+= "<b>" + member
.getTitleCache() + "</b>";
2297 collectorString
+= member
.getTitleCache();
2302 collectorString
= collectorA
.getTitleCache();
2305 return collectorString
;
2306 } catch (Exception e
) {
2307 state
.getResult().addException(e
, "An unexpected error occurred when creating collector string for "
2308 + cdmBaseStr(fieldUnit
) + ": " + e
.getMessage());
2315 * Returns a string representation of the {@link CdmBase cdmBase} object for
2318 private String
cdmBaseStr(CdmBase cdmBase
) {
2319 if (cdmBase
== null) {
2320 return "-no object available-";
2322 return cdmBase
.getClass().getSimpleName() + ": " + cdmBase
.getUuid();
2327 protected boolean doCheck(ColDpExportState state
) {
2332 protected boolean isIgnore(ColDpExportState state
) {