add try/catch for handling of description elements
[cdmlib.git] / cdmlib-io / src / main / java / eu / etaxonomy / cdm / io / cdmLight / CdmLightClassificationExport.java
1 /**
2 * Copyright (C) 2017 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
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.
8 */
9 package eu.etaxonomy.cdm.io.cdmLight;
10
11 import java.io.File;
12 import java.util.ArrayList;
13 import java.util.Collections;
14 import java.util.HashSet;
15 import java.util.Iterator;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.Set;
19 import java.util.UUID;
20
21 import org.apache.commons.lang3.StringUtils;
22 import org.springframework.stereotype.Component;
23
24 import eu.etaxonomy.cdm.common.CdmUtils;
25 import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;
26 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
27 import eu.etaxonomy.cdm.io.common.CdmExportBase;
28 import eu.etaxonomy.cdm.io.common.ExportResult.ExportResultState;
29 import eu.etaxonomy.cdm.io.common.ICdmExport;
30 import eu.etaxonomy.cdm.io.common.TaxonNodeOutStreamPartitioner;
31 import eu.etaxonomy.cdm.io.common.XmlExportState;
32 import eu.etaxonomy.cdm.io.common.mapping.out.IExportTransformer;
33 import eu.etaxonomy.cdm.model.agent.AgentBase;
34 import eu.etaxonomy.cdm.model.agent.Person;
35 import eu.etaxonomy.cdm.model.agent.Team;
36 import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
37 import eu.etaxonomy.cdm.model.common.Annotation;
38 import eu.etaxonomy.cdm.model.common.AnnotationType;
39 import eu.etaxonomy.cdm.model.common.CdmBase;
40 import eu.etaxonomy.cdm.model.common.DefinedTerm;
41 import eu.etaxonomy.cdm.model.common.ICdmBase;
42 import eu.etaxonomy.cdm.model.common.IIdentifiableEntity;
43 import eu.etaxonomy.cdm.model.common.Language;
44 import eu.etaxonomy.cdm.model.common.LanguageString;
45 import eu.etaxonomy.cdm.model.description.CommonTaxonName;
46 import eu.etaxonomy.cdm.model.description.DescriptionBase;
47 import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
48 import eu.etaxonomy.cdm.model.description.DescriptionElementSource;
49 import eu.etaxonomy.cdm.model.description.Distribution;
50 import eu.etaxonomy.cdm.model.description.Feature;
51 import eu.etaxonomy.cdm.model.description.IndividualsAssociation;
52 import eu.etaxonomy.cdm.model.description.SpecimenDescription;
53 import eu.etaxonomy.cdm.model.description.TaxonDescription;
54 import eu.etaxonomy.cdm.model.description.TaxonNameDescription;
55 import eu.etaxonomy.cdm.model.description.TextData;
56 import eu.etaxonomy.cdm.model.location.NamedArea;
57 import eu.etaxonomy.cdm.model.media.Media;
58 import eu.etaxonomy.cdm.model.media.MediaRepresentation;
59 import eu.etaxonomy.cdm.model.media.MediaRepresentationPart;
60 import eu.etaxonomy.cdm.model.name.HomotypicalGroup;
61 import eu.etaxonomy.cdm.model.name.HomotypicalGroupNameComparator;
62 import eu.etaxonomy.cdm.model.name.NameTypeDesignation;
63 import eu.etaxonomy.cdm.model.name.NomenclaturalStatus;
64 import eu.etaxonomy.cdm.model.name.Rank;
65 import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;
66 import eu.etaxonomy.cdm.model.name.TaxonName;
67 import eu.etaxonomy.cdm.model.name.TypeComparator;
68 import eu.etaxonomy.cdm.model.name.TypeDesignationBase;
69 import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
70 import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
71 import eu.etaxonomy.cdm.model.occurrence.GatheringEvent;
72 import eu.etaxonomy.cdm.model.occurrence.MediaSpecimen;
73 import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
74 import eu.etaxonomy.cdm.model.reference.Reference;
75 import eu.etaxonomy.cdm.model.reference.ReferenceType;
76 import eu.etaxonomy.cdm.model.taxon.Synonym;
77 import eu.etaxonomy.cdm.model.taxon.Taxon;
78 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
79 import eu.etaxonomy.cdm.strategy.exceptions.UnknownCdmTypeException;
80
81 /**
82 * @author k.luther
83 * @date 15.03.2017
84 */
85 @Component
86 public class CdmLightClassificationExport
87 extends CdmExportBase<CdmLightExportConfigurator, CdmLightExportState, IExportTransformer, File>
88 implements ICdmExport<CdmLightExportConfigurator, CdmLightExportState>{
89
90
91 private static final long serialVersionUID = 2518643632756927053L;
92 private static final String STD_TEAM_CONCATINATION = ", ";
93 private static final String FINAL_TEAM_CONCATINATION = " & ";
94
95 private static final String IPNI_NAME_IDENTIFIER = "Ipni Name Identifier";
96 private static final String TROPICOS_NAME_IDENTIFIER = "Tropicos Name Identifier";
97 private static final String WFO_NAME_IDENTIFIER = "WFO Name Identifier";
98
99 public CdmLightClassificationExport() {
100 super();
101 this.ioName = this.getClass().getSimpleName();
102
103 }
104
105 /**
106 * {@inheritDoc}
107 */
108 @Override
109 protected void doInvoke(CdmLightExportState state) {
110 try {
111
112 IProgressMonitor monitor = state.getConfig().getProgressMonitor();
113 CdmLightExportConfigurator config = state.getConfig();
114 config.setFieldsTerminatedBy(",");
115
116 // if (config.getTaxonNodeFilter().getTaxonNodesFilter().isEmpty() && config.getTaxonNodeFilter().getClassificationFilter().isEmpty()){
117 // //TODO
118 // state.setEmptyData();
119 // return;
120 // }
121
122
123
124 // for (LogicFilter<Classification> classificationFilter : config.getTaxonNodeFilter().getClassificationFilter()){
125 // UUID classificationUuid = classificationFilter.getUuid();
126 // Classification classification = getClassificationService().find(classificationUuid);
127 // if (classification == null){
128 // String message = String.format("Classification for given classification UUID not found. No data imported for %s", classificationUuid.toString());
129 // state.getResult().addWarning(message);
130 // }else{
131 // TaxonNode root = classification.getRootNode();
132 // UUID uuid = root.getUuid();
133 // root = getTaxonNodeService().load(uuid);
134 // handleSingleClassification(state, root.getUuid());
135 // }
136 // }
137
138
139 @SuppressWarnings("unchecked")
140 TaxonNodeOutStreamPartitioner<XmlExportState> partitioner
141 = TaxonNodeOutStreamPartitioner.NewInstance(
142 this, state, state.getConfig().getTaxonNodeFilter(),
143 100, monitor, null);
144
145
146 monitor.subTask("Start partitioning");
147
148 TaxonNode node = partitioner.next();
149 while (node != null){
150 handleTaxonNode(state, node.getUuid());
151 node = partitioner.next();
152 }
153
154
155 // for (LogicFilter<TaxonNode> taxonNodeFilter : config.getTaxonNodeFilter().getTaxonNodesFilter()){
156 // UUID nodeUuid = taxonNodeFilter.getUuid();
157 // handleSingleClassification(state, nodeUuid);
158 // }
159 state.getProcessor().createFinalResult(state);
160 } catch (Exception e) {
161 state.getResult().addException(e, "An unexpected error occurred in main method doInvoke() " +
162 e.getMessage());
163 }
164 }
165
166 /**
167 * @param state
168 * @param classificationUuid
169 */
170 private void handleTaxonNode(CdmLightExportState state, UUID taxonNodeUuid) {
171 try {
172 TaxonNode taxonNode = getTaxonNodeService().find(taxonNodeUuid);
173
174 if (taxonNode == null){
175 String message = String.format("TaxonNode for given taxon node UUID not found. No data imported for %s", taxonNodeUuid.toString());
176 //TODO
177 state.getResult().addWarning(message);
178 }else{
179 TaxonNode root = taxonNode;
180 if (root.hasTaxon()){
181 handleTaxon(state, root);
182 }else{
183 for (TaxonNode child : root.getChildNodes()){
184 handleTaxon(state, child);
185 //TODO progress monitor
186 }
187 }
188 }
189 } catch (Exception e) {
190 state.getResult().addException(e, "An unexpected error occurred when handling classification " +
191 taxonNodeUuid + ": " + e.getMessage() + e.getStackTrace());
192 }
193 }
194
195 /**
196 * @param state
197 * @param taxon
198 */
199 private void handleTaxon(CdmLightExportState state, TaxonNode taxonNode) {
200 try{
201 // Taxon taxon = taxonNode.getTaxon();
202 if (taxonNode == null){
203 state.getResult().addError ("The taxonNode was null.", "handleTaxon");
204 state.getResult().setState(ExportResultState.INCOMPLETE_WITH_ERROR);
205 return;
206 }
207 if (taxonNode.getTaxon() == null){
208 state.getResult().addError ("There was a taxon node without a taxon: " + taxonNode.getUuid(), "handleTaxon");
209 state.getResult().setState(ExportResultState.INCOMPLETE_WITH_ERROR);
210 }else{
211 Taxon taxon = taxonNode.getTaxon();
212 try{
213 TaxonName name = taxon.getName();
214 handleName(state, name);
215 for (Synonym syn : taxon.getSynonyms()){
216 handleSynonym(state, syn);
217 }
218
219
220 CdmLightExportTable table = CdmLightExportTable.TAXON;
221 String[] csvLine = new String[table.getSize()];
222
223 csvLine[table.getIndex(CdmLightExportTable.TAXON_ID)] = getId(state, taxon);
224 csvLine[table.getIndex(CdmLightExportTable.NAME_FK)] = getId(state, name);
225 Taxon parent = (taxonNode.getParent()==null) ? null : taxonNode.getParent().getTaxon();
226 csvLine[table.getIndex(CdmLightExportTable.PARENT_FK)] = getId(state, parent);
227 csvLine[table.getIndex(CdmLightExportTable.SEC_REFERENCE_FK)] = getId(state, taxon.getSec());
228 csvLine[table.getIndex(CdmLightExportTable.SEC_REFERENCE)] = getTitleCache(taxon.getSec());
229 csvLine[table.getIndex(CdmLightExportTable.CLASSIFICATION_ID)] = getId(state, taxonNode.getClassification());
230 csvLine[table.getIndex(CdmLightExportTable.CLASSIFICATION_TITLE)] = taxonNode.getClassification().getTitleCache();
231
232 state.getProcessor().put(table, taxon, csvLine);
233 handleDescriptions(state, taxon);
234 }catch(Exception e){
235 state.getResult().addException (e, "An unexpected problem occurred when trying to export "
236 + "taxon with id " + taxon.getId());
237 state.getResult().setState(ExportResultState.INCOMPLETE_WITH_ERROR);
238 }
239 }
240
241 taxonNode.removeNullValueFromChildren();
242 // for (TaxonNode child: taxonNode.getChildNodes()){
243 // handleTaxon(state, child);
244 // }
245 }catch (Exception e){
246 state.getResult().addException(e, "An unexpected error occurred when handling the taxon node of " +
247 cdmBaseStr(taxonNode.getTaxon()) + ": " + e.getMessage());
248 }
249 }
250
251 /**
252 * @param state
253 * @param taxon
254 */
255 private void handleDescriptions(CdmLightExportState state, CdmBase cdmBase) {
256 try{
257 if (cdmBase instanceof Taxon){
258 Taxon taxon = HibernateProxyHelper.deproxy(cdmBase, Taxon.class);
259 Set<TaxonDescription> descriptions = taxon.getDescriptions();
260 List<DescriptionElementBase> simpleFacts = new ArrayList<>();
261 List<DescriptionElementBase> specimenFacts = new ArrayList<>();
262 List<DescriptionElementBase> distributionFacts = new ArrayList<>();
263 List<DescriptionElementBase> commonNameFacts = new ArrayList<>();
264 List<DescriptionElementBase> usageFacts = new ArrayList<>();
265 for (TaxonDescription description: descriptions){
266 if (description.getElements() != null){
267 for (DescriptionElementBase element: description.getElements()){
268 element = CdmBase.deproxy(element);
269 if (element.getFeature().equals(Feature.COMMON_NAME())){
270 commonNameFacts.add(element);
271 }else if (element.getFeature().equals(Feature.DISTRIBUTION())){
272 distributionFacts.add(element);
273 }else if (element instanceof IndividualsAssociation || isSpecimenFeature(element.getFeature())){
274 specimenFacts.add(element);
275 }else{
276 simpleFacts.add(element);
277 }
278 }
279 }
280 }
281 if (!commonNameFacts.isEmpty()){
282 handleCommonNameFacts(state, taxon, commonNameFacts);
283 }
284 if (!distributionFacts.isEmpty()){
285 handleDistributionFacts(state, taxon, distributionFacts);
286 }
287 if (!specimenFacts.isEmpty()){
288 handleSpecimenFacts(state, taxon, specimenFacts);
289 }
290 if (!simpleFacts.isEmpty()){
291 handleSimpleFacts(state, taxon, simpleFacts);
292 }
293 } else if (cdmBase instanceof TaxonName){
294 TaxonName name = CdmBase.deproxy(cdmBase, TaxonName.class);
295 Set<TaxonNameDescription> descriptions = name.getDescriptions();
296 List<DescriptionElementBase> simpleFacts = new ArrayList<>();
297 for (TaxonNameDescription description: descriptions){
298 if (description.getElements() != null){
299 for (DescriptionElementBase element: description.getElements()){
300 if (!element.getFeature().equals(Feature.PROTOLOGUE())){
301 simpleFacts.add(element);
302 }
303 }
304 }
305 }
306 if (!simpleFacts.isEmpty()){
307 handleSimpleFacts(state, name, simpleFacts);
308 }
309 }
310 }catch (Exception e){
311 state.getResult().addException(e, "An unexpected error occurred when handling description of" +
312 cdmBaseStr(cdmBase) + ": " + e.getMessage());
313 }
314 }
315
316
317 /**
318 * @param feature
319 * @return
320 */
321 private boolean isSpecimenFeature(Feature feature) {
322 //TODO allow user defined specimen features
323 if (feature == null){
324 return false;
325 }else if (feature.isSupportsIndividualAssociation()){
326 return true;
327 }else{
328 return feature.equals(Feature.SPECIMEN()) || feature.equals(Feature.INDIVIDUALS_ASSOCIATION())
329 || feature.equals(Feature.MATERIALS_EXAMINED()) || feature.equals(Feature.OBSERVATION())
330 || feature.equals(Feature.OCCURRENCE())
331 ;
332 }
333 }
334
335 /**
336 * @param state
337 * @param taxon
338 * @param simpleFacts
339 */
340 private void handleSimpleFacts(CdmLightExportState state, CdmBase cdmBase,
341 List<DescriptionElementBase> simpleFacts) {
342 try {
343 CdmLightExportTable table = CdmLightExportTable.SIMPLE_FACT;
344 CdmLightExportTable tableMedia = CdmLightExportTable.MEDIA;
345 for (DescriptionElementBase element: simpleFacts){
346 if (element.getModifyingText().isEmpty() && !element.getMedia().isEmpty()){
347 handleSimpleMediaFact(state, cdmBase, tableMedia, element);
348 }else{
349 handleSingleSimpleFact(state, cdmBase, table, element);
350 }
351 }
352 } catch (Exception e) {
353 state.getResult().addException(e, "An unexpected error occurred when handling simple facts for " +
354 cdmBaseStr(cdmBase) + ": " + e.getMessage());
355 }
356 }
357
358 /**
359 * @param state
360 * @param cdmBase
361 * @param tableMedia
362 * @param element
363 */
364 private void handleSimpleMediaFact(CdmLightExportState state, CdmBase cdmBase, CdmLightExportTable table,
365 DescriptionElementBase element) {
366 try {
367 String[] csvLine;
368 handleSource(state, element, CdmLightExportTable.MEDIA);
369
370 if (element instanceof TextData){
371 TextData textData = (TextData)element;
372 csvLine = new String[table.getSize()];
373 csvLine[table.getIndex(CdmLightExportTable.FACT_ID)] = getId(state, element);
374 if (cdmBase instanceof Taxon){
375 csvLine[table.getIndex(CdmLightExportTable.TAXON_FK)] = getId(state, cdmBase);
376 csvLine[table.getIndex(CdmLightExportTable.NAME_FK)] = "";
377 }else if (cdmBase instanceof TaxonName){
378 csvLine[table.getIndex(CdmLightExportTable.TAXON_FK)] = "";
379 csvLine[table.getIndex(CdmLightExportTable.NAME_FK)] = getId(state, cdmBase);
380 }
381
382
383 String mediaUris = "";
384 for (Media media: textData.getMedia()){
385 String mediaString = extractMediaUris(media.getRepresentations().iterator());
386 if (!StringUtils.isBlank(mediaString)){
387 mediaUris += mediaString + ";";
388 }
389 else{
390 state.getResult().addWarning("Empty Media object for uuid: " +
391 cdmBase.getUuid() + " uuid of media: " + media.getUuid());
392 }
393 }
394 csvLine[table.getIndex(CdmLightExportTable.MEDIA_URI)] = mediaUris;
395
396 }
397 } catch (Exception e) {
398 state.getResult().addException(e, "An unexpected error occurred when handling single simple fact " +
399 cdmBaseStr(element) + ": " + e.getMessage());
400 }
401
402 }
403
404 /**
405 * @param state
406 * @param cdmBase
407 * @param table
408 * @param element
409 */
410 private void handleSingleSimpleFact(CdmLightExportState state, CdmBase cdmBase, CdmLightExportTable table,
411 DescriptionElementBase element) {
412 try {
413 String[] csvLine;
414 handleSource(state, element, CdmLightExportTable.SIMPLE_FACT);
415
416 if (element instanceof TextData){
417 TextData textData = (TextData)element;
418 csvLine = new String[table.getSize()];
419 csvLine[table.getIndex(CdmLightExportTable.FACT_ID)] = getId(state, element);
420 if (cdmBase instanceof Taxon){
421 csvLine[table.getIndex(CdmLightExportTable.TAXON_FK)] = getId(state, cdmBase);
422 csvLine[table.getIndex(CdmLightExportTable.NAME_FK)] = "";
423 }else if (cdmBase instanceof TaxonName){
424 csvLine[table.getIndex(CdmLightExportTable.TAXON_FK)] = "";
425 csvLine[table.getIndex(CdmLightExportTable.NAME_FK)] = getId(state, cdmBase);
426 }
427 csvLine[table.getIndex(CdmLightExportTable.FACT_CATEGORY)] = textData.getFeature().getLabel();
428
429 String mediaUris = "";
430 for (Media media: textData.getMedia()){
431 String mediaString = extractMediaUris(media.getRepresentations().iterator());
432 if (!StringUtils.isBlank(mediaString)){
433 mediaUris += mediaString + ";";
434 }
435 else{
436 state.getResult().addWarning("Empty Media object for uuid: " +
437 cdmBase.getUuid() + " uuid of media: " + media.getUuid());
438 }
439 }
440 csvLine[table.getIndex(CdmLightExportTable.MEDIA_URI)] = mediaUris;
441 if (textData.getFeature().equals(Feature.CITATION())){
442 // csvLine[table.getIndex(CdmLightExportTable.TAXON_FK)] = getId(state, cdmBase);
443 state.getProcessor().put(table, textData, csvLine);
444 }else if (!textData.getMultilanguageText().isEmpty()){
445 for (Language language: textData.getMultilanguageText().keySet()){
446 String[] csvLineLanguage = csvLine.clone();
447 LanguageString langString = textData.getLanguageText(language);
448
449 csvLineLanguage[table.getIndex(CdmLightExportTable.FACT_TEXT)] = langString.getText();
450 csvLineLanguage[table.getIndex(CdmLightExportTable.LANGUAGE)] = language.getLabel();
451 state.getProcessor().put(table, textData, csvLineLanguage);
452 }
453 } else{
454 state.getProcessor().put(table, textData, csvLine);
455 }
456 }
457 } catch (Exception e) {
458 state.getResult().addException(e, "An unexpected error occurred when handling single simple fact " +
459 cdmBaseStr(element) + ": " + e.getMessage());
460 }
461 }
462
463
464 /**
465 * @param state
466 * @param specimenFacts
467 */
468 private void handleSpecimenFacts(CdmLightExportState state, Taxon taxon, List<DescriptionElementBase> specimenFacts) {
469 CdmLightExportTable table = CdmLightExportTable.SPECIMEN_FACT;
470
471 for (DescriptionElementBase element: specimenFacts){
472 try {
473 String[] csvLine = new String[table.getSize()];
474 csvLine[table.getIndex(CdmLightExportTable.FACT_ID)] = getId(state, element);
475 csvLine[table.getIndex(CdmLightExportTable.TAXON_FK)] = getId(state, taxon);
476 handleSource(state, element, table);
477 csvLine[table.getIndex(CdmLightExportTable.SPECIMEN_NOTES)] = createAnnotationsString(element.getAnnotations());
478
479 if (element instanceof IndividualsAssociation){
480
481 IndividualsAssociation indAssociation = (IndividualsAssociation)element;
482 if (state.getSpecimenFromStore(indAssociation.getAssociatedSpecimenOrObservation().getId()) == null){
483 SpecimenOrObservationBase<?> specimenBase = HibernateProxyHelper.deproxy(indAssociation.getAssociatedSpecimenOrObservation());
484
485 if (specimenBase instanceof SpecimenOrObservationBase){
486 SpecimenOrObservationBase derivedUnit = specimenBase;
487 handleSpecimen(state, derivedUnit);
488 csvLine[table.getIndex(CdmLightExportTable.SPECIMEN_FK)] = getId(state, indAssociation.getAssociatedSpecimenOrObservation());
489 }else{
490 //field units are not supported
491 state.getResult().addError("The associated Specimen of taxon " + taxon.getUuid() + " is not an DerivedUnit. Could not be exported.");
492 }
493 }
494 } else if (element instanceof TextData){
495 TextData textData = HibernateProxyHelper.deproxy(element, TextData.class);
496 csvLine[table.getIndex(CdmLightExportTable.SPECIMEN_DESCRIPTION)] = createMultilanguageString(textData.getMultilanguageText());
497 }
498 state.getProcessor().put(table, element, csvLine);
499 } catch (Exception e) {
500 state.getResult().addException(e, "An unexpected error occurred when handling single specimen fact " +
501 cdmBaseStr(element) + ": " + e.getMessage());
502 }
503 }
504 }
505
506 /**
507 * @param multilanguageText
508 * @return
509 */
510 private String createMultilanguageString(Map<Language, LanguageString> multilanguageText) {
511 String text = "";
512 int index = multilanguageText.size();
513 for(LanguageString langString: multilanguageText.values()){
514 text += langString.getText();
515 if (index > 1){
516 text += "; ";
517 }
518 index --;
519 }
520
521 return text;
522 }
523
524 /**
525 * @param annotations
526 * @return
527 */
528 private String createAnnotationsString(Set<Annotation> annotations) {
529 StringBuffer strBuff = new StringBuffer();
530
531 for (Annotation ann:annotations){
532 if (ann.getAnnotationType() == null ||!ann.getAnnotationType().equals(AnnotationType.TECHNICAL())){
533 strBuff.append(ann.getText());
534 strBuff.append("; ");
535 }
536 }
537
538 if (strBuff.length() > 2){
539 return strBuff.substring(0, strBuff.length()-2);
540 }else{
541 return null;
542 }
543 }
544
545 /**
546 * @param state
547 * @param taxon
548 * @param element
549 */
550 private void handleSource(CdmLightExportState state, DescriptionElementBase element, CdmLightExportTable factsTable) {
551 CdmLightExportTable table = CdmLightExportTable.FACT_SOURCES;
552 try {
553 Set<DescriptionElementSource> sources = element.getSources();
554
555 for (DescriptionElementSource source: sources){
556
557 String[] csvLine = new String[table.getSize()];
558 Reference ref = source.getCitation();
559 if ((ref == null) && (source.getNameUsedInSource() == null)){
560 continue;
561 }
562 if (ref != null){
563 if (state.getReferenceFromStore(ref.getId()) == null){
564 handleReference(state, ref);
565
566 }
567 csvLine[table.getIndex(CdmLightExportTable.REFERENCE_FK)] = getId(state, ref);
568 }
569 csvLine[table.getIndex(CdmLightExportTable.FACT_FK)] = getId(state, element);
570
571 csvLine[table.getIndex(CdmLightExportTable.NAME_IN_SOURCE_FK)] = getId(state, source.getNameUsedInSource());
572 csvLine[table.getIndex(CdmLightExportTable.FACT_TYPE)] = factsTable.getTableName();
573 if ( StringUtils.isBlank(csvLine[table.getIndex(CdmLightExportTable.REFERENCE_FK)]) && StringUtils.isBlank(csvLine[table.getIndex(CdmLightExportTable.NAME_IN_SOURCE_FK)])){
574 continue;
575 }
576 state.getProcessor().put(table, source, csvLine);
577
578 }
579 } catch (Exception e) {
580 state.getResult().addException(e, "An unexpected error occurred when handling single source " +
581 cdmBaseStr(element) + ": " + e.getMessage());
582 }
583
584 }
585
586 /**
587 * @param state
588 * @param distributionFacts
589 */
590 private void handleDistributionFacts(CdmLightExportState state, Taxon taxon, List<DescriptionElementBase> distributionFacts) {
591 CdmLightExportTable table = CdmLightExportTable.GEOGRAPHIC_AREA_FACT;
592
593 for (DescriptionElementBase element: distributionFacts){
594 try {
595 if (element instanceof Distribution){
596 String[] csvLine = new String[table.getSize()];
597 Distribution distribution = (Distribution)element;
598 csvLine[table.getIndex(CdmLightExportTable.FACT_ID)] = getId(state, element);
599 handleSource(state, element, table);
600 csvLine[table.getIndex(CdmLightExportTable.TAXON_FK)] = getId(state, taxon);
601 if (distribution.getArea() != null){
602 csvLine[table.getIndex(CdmLightExportTable.AREA_LABEL)] = distribution.getArea().getLabel();
603 }
604 if (distribution.getStatus() != null){
605 csvLine[table.getIndex(CdmLightExportTable.STATUS_LABEL)] = distribution.getStatus().getLabel();
606 }
607 state.getProcessor().put(table, distribution, csvLine);
608 } else{
609 state.getResult().addError("The distribution description for the taxon " + taxon.getUuid() + " is not of type distribution. Could not be exported. UUID of the description element: " + element.getUuid());
610 }
611 } catch (Exception e) {
612 state.getResult().addException(e, "An unexpected error occurred when handling single distribution " +
613 cdmBaseStr(element) + ": " + e.getMessage());
614 }
615 }
616 }
617
618 /**
619 * @param state
620 * @param commonNameFacts
621 */
622 private void handleCommonNameFacts(CdmLightExportState state, Taxon taxon, List<DescriptionElementBase> commonNameFacts) {
623 CdmLightExportTable table = CdmLightExportTable.COMMON_NAME_FACT;
624
625 for (DescriptionElementBase element: commonNameFacts){
626 try {
627 if (element instanceof CommonTaxonName){
628 String[] csvLine = new String[table.getSize()];
629 CommonTaxonName commonName = (CommonTaxonName)element;
630 csvLine[table.getIndex(CdmLightExportTable.FACT_ID)] = getId(state, element);
631 handleSource(state, element, table);
632 csvLine[table.getIndex(CdmLightExportTable.TAXON_FK)] = getId(state, taxon);
633 if (commonName.getName() != null){csvLine[table.getIndex(CdmLightExportTable.FACT_TEXT)] = commonName.getName();}
634 if (commonName.getLanguage() != null){csvLine[table.getIndex(CdmLightExportTable.LANGUAGE)] = commonName.getLanguage().getLabel();}
635 if (commonName.getArea() != null){ csvLine[table.getIndex(CdmLightExportTable.AREA_LABEL)] = commonName.getArea().getLabel();}
636 state.getProcessor().put(table, commonName, csvLine);
637 } else{
638 state.getResult().addError("The distribution description for the taxon " + taxon.getUuid() + " is not of type distribution. Could not be exported. UUID of the description element: " + element.getUuid());
639 }
640 } catch (Exception e) {
641 state.getResult().addException(e, "An unexpected error occurred when handling single common name " +
642 cdmBaseStr(element) + ": " + e.getMessage());
643 }
644 }
645 }
646
647 /**
648 * @param sec
649 * @return
650 */
651 private String getTitleCache(IIdentifiableEntity identEntity) {
652 if (identEntity == null){
653 return "";
654 }
655 //TODO refresh?
656 return identEntity.getTitleCache();
657 }
658
659 /**
660 * @param state
661 * @param taxon
662 * @return
663 */
664 private String getId(CdmLightExportState state, ICdmBase cdmBase) {
665 if (cdmBase == null){
666 return "";
667 }
668 //TODO make configurable
669 return cdmBase.getUuid().toString();
670 }
671
672 /**
673 * @param state
674 * @param syn
675 */
676 private void handleSynonym(CdmLightExportState state, Synonym syn) {
677 try {
678
679 TaxonName name = syn.getName();
680 handleName(state, name);
681
682 CdmLightExportTable table = CdmLightExportTable.SYNONYM;
683 String[] csvLine = new String[table.getSize()];
684
685 csvLine[table.getIndex(CdmLightExportTable.SYNONYM_ID)] = getId(state, syn);
686 csvLine[table.getIndex(CdmLightExportTable.TAXON_FK)] = getId(state, syn.getAcceptedTaxon());
687 csvLine[table.getIndex(CdmLightExportTable.NAME_FK)] = getId(state, name);
688 csvLine[table.getIndex(CdmLightExportTable.SEC_REFERENCE_FK)] = getId(state, syn.getSec());
689 csvLine[table.getIndex(CdmLightExportTable.SEC_REFERENCE)] = getTitleCache(syn.getSec());
690
691 state.getProcessor().put(table, syn, csvLine);
692 } catch (Exception e) {
693 state.getResult().addException(e, "An unexpected error occurred when handling synonym " +
694 cdmBaseStr(syn) + ": " + e.getMessage());
695 }
696 }
697
698 /**
699 * @param state
700 * @param name
701 */
702 private void handleName(CdmLightExportState state, TaxonName name) {
703 if (name == null){
704 return;
705 }
706 try {
707 Rank rank = name.getRank();
708 CdmLightExportTable table = CdmLightExportTable.SCIENTIFIC_NAME;
709 name = HibernateProxyHelper.deproxy(name);
710 String[] csvLine = new String[table.getSize()];
711
712 csvLine[table.getIndex(CdmLightExportTable.NAME_ID)] = getId(state, name);
713 if (name.getLsid() != null){
714 csvLine[table.getIndex(CdmLightExportTable.LSID)] = name.getLsid().getLsid();
715 }else{
716 csvLine[table.getIndex(CdmLightExportTable.LSID)] = "";
717 }
718
719 handleIdentifier(state, name);
720 handleDescriptions(state, name);
721
722 csvLine[table.getIndex(CdmLightExportTable.RANK)] = getTitleCache(rank);
723 if (rank != null){
724 csvLine[table.getIndex(CdmLightExportTable.RANK_SEQUENCE)] = String.valueOf(rank.getOrderIndex());
725 if (rank.isInfraGeneric()){
726 try {
727 csvLine[table.getIndex(CdmLightExportTable.INFRAGENERIC_RANK)] = name.getRank().getInfraGenericMarker();
728 } catch (UnknownCdmTypeException e) {
729 state.getResult().addError("Infrageneric marker expected but not available for rank " + name.getRank().getTitleCache());
730 }
731 }
732 if (rank.isInfraSpecific()){
733 csvLine[table.getIndex(CdmLightExportTable.INFRASPECIFIC_RANK)] = name.getRank().getAbbreviation();
734 }
735 }else{
736 csvLine[table.getIndex(CdmLightExportTable.RANK_SEQUENCE)] = "";
737 }
738 if (name.isProtectedTitleCache()){
739 csvLine[table.getIndex(CdmLightExportTable.FULL_NAME_WITH_AUTHORS)] =name.getTitleCache();
740 }else{
741 //TODO: adapt the tropicos titlecache creation
742 csvLine[table.getIndex(CdmLightExportTable.FULL_NAME_WITH_AUTHORS)] = name.getTitleCache();
743 }
744 csvLine[table.getIndex(CdmLightExportTable.FULL_NAME_NO_AUTHORS)] = name.getNameCache();
745 csvLine[table.getIndex(CdmLightExportTable.GENUS_UNINOMIAL)] = name.getGenusOrUninomial();
746
747 csvLine[table.getIndex(CdmLightExportTable.INFRAGENERIC_EPITHET)] = name.getInfraGenericEpithet();
748 csvLine[table.getIndex(CdmLightExportTable.SPECIFIC_EPITHET)] = name.getSpecificEpithet();
749
750 csvLine[table.getIndex(CdmLightExportTable.INFRASPECIFIC_EPITHET)] = name.getInfraSpecificEpithet();
751 csvLine[table.getIndex(CdmLightExportTable.BAS_AUTHORTEAM_FK)] = getId(state,name.getBasionymAuthorship());
752 if (name.getBasionymAuthorship() != null){
753 if (state.getAuthorFromStore(name.getBasionymAuthorship().getId()) == null) {
754 handleAuthor(state, name.getBasionymAuthorship());
755 }
756 }
757 csvLine[table.getIndex(CdmLightExportTable.BAS_EX_AUTHORTEAM_FK)] = getId(state, name.getExBasionymAuthorship());
758 if (name.getExBasionymAuthorship() != null){
759 if (state.getAuthorFromStore(name.getExBasionymAuthorship().getId()) == null) {
760 handleAuthor(state, name.getExBasionymAuthorship());
761 }
762
763 }
764 csvLine[table.getIndex(CdmLightExportTable.COMB_AUTHORTEAM_FK)] = getId(state,name.getCombinationAuthorship());
765 if (name.getCombinationAuthorship() != null){
766 if (state.getAuthorFromStore(name.getCombinationAuthorship().getId()) == null) {
767 handleAuthor(state, name.getCombinationAuthorship());
768 }
769 }
770 csvLine[table.getIndex(CdmLightExportTable.COMB_EX_AUTHORTEAM_FK)] = getId(state, name.getExCombinationAuthorship());
771 if (name.getExCombinationAuthorship() != null){
772 if (state.getAuthorFromStore(name.getExCombinationAuthorship().getId()) == null) {
773 handleAuthor(state, name.getExCombinationAuthorship());
774 }
775
776 }
777
778 csvLine[table.getIndex(CdmLightExportTable.AUTHOR_TEAM_STRING)] = name.getAuthorshipCache();
779
780 Reference nomRef = (Reference)name.getNomenclaturalReference();
781
782 if (nomRef != null){
783 if (state.getReferenceFromStore(nomRef.getId()) == null){
784 handleReference(state, nomRef);
785 }
786 csvLine[table.getIndex(CdmLightExportTable.REFERENCE_FK)] = getId(state, nomRef);
787 csvLine[table.getIndex(CdmLightExportTable.PUBLICATION_TYPE)] = nomRef.getType().name();
788 if (nomRef.getVolume() != null){
789 csvLine[table.getIndex(CdmLightExportTable.VOLUME_ISSUE)] = nomRef.getVolume();
790 csvLine[table.getIndex(CdmLightExportTable.COLLATION)] = createCollatation(name);
791 }
792 if (nomRef.getDatePublished() != null){
793 csvLine[table.getIndex(CdmLightExportTable.DATE_PUBLISHED)] = nomRef.getTimePeriodPublishedString();
794 csvLine[table.getIndex(CdmLightExportTable.YEAR_PUBLISHED)] = nomRef.getDatePublished().getYear();
795 csvLine[table.getIndex(CdmLightExportTable.VERBATIM_DATE)] = null;
796 }
797 if (name.getNomenclaturalMicroReference() != null){
798 csvLine[table.getIndex(CdmLightExportTable.DETAIL)] = name.getNomenclaturalMicroReference();
799 }
800 nomRef = HibernateProxyHelper.deproxy(nomRef);
801 if (nomRef.getInReference() != null){
802 Reference inReference = nomRef.getInReference();
803 if (inReference.getDatePublished() != null && nomRef.getDatePublished() == null){
804 csvLine[table.getIndex(CdmLightExportTable.DATE_PUBLISHED)] = inReference.getDatePublishedString();
805 csvLine[table.getIndex(CdmLightExportTable.YEAR_PUBLISHED)] = inReference.getDatePublished().getYear();
806 }
807 if (nomRef.getVolume() == null && inReference.getVolume() != null){
808 csvLine[table.getIndex(CdmLightExportTable.VOLUME_ISSUE)] = inReference.getVolume();
809 csvLine[table.getIndex(CdmLightExportTable.COLLATION)] = createCollatation(name);
810 }
811 if (inReference.getInReference() != null){
812 inReference = inReference.getInReference();
813 }
814 if (inReference.getAbbrevTitle() == null){
815 csvLine[table.getIndex(CdmLightExportTable.ABBREV_TITLE)] = CdmUtils.Nz(inReference.getAbbrevTitleCache());
816 }else{
817 csvLine[table.getIndex(CdmLightExportTable.ABBREV_TITLE)] = CdmUtils.Nz(inReference.getAbbrevTitle());
818 }
819 if (inReference.getTitle() == null){
820 csvLine[table.getIndex(CdmLightExportTable.FULL_TITLE)] = CdmUtils.Nz(inReference.getTitleCache());
821 }else{
822 csvLine[table.getIndex(CdmLightExportTable.FULL_TITLE)] = CdmUtils.Nz(inReference.getTitle());
823 }
824
825
826 TeamOrPersonBase<?> author = inReference.getAuthorship();
827 if (author != null && (nomRef.isOfType(ReferenceType.BookSection) || nomRef.isOfType(ReferenceType.Section))){
828 csvLine[table.getIndex(CdmLightExportTable.ABBREV_REF_AUTHOR)] = CdmUtils.Nz(author.getNomenclaturalTitle());
829 csvLine[table.getIndex(CdmLightExportTable.FULL_REF_AUTHOR)] = CdmUtils.Nz(author.getTitleCache());
830 }else{
831 csvLine[table.getIndex(CdmLightExportTable.ABBREV_REF_AUTHOR)] = "";
832 csvLine[table.getIndex(CdmLightExportTable.FULL_REF_AUTHOR)] = "";
833 }
834 }else{
835 if (nomRef.getAbbrevTitle() == null){
836 csvLine[table.getIndex(CdmLightExportTable.ABBREV_TITLE)] = CdmUtils.Nz(nomRef.getAbbrevTitleCache());
837 }else{
838 csvLine[table.getIndex(CdmLightExportTable.ABBREV_TITLE)] = CdmUtils.Nz(nomRef.getAbbrevTitle());
839 }
840 if (nomRef.getTitle() == null){
841 csvLine[table.getIndex(CdmLightExportTable.FULL_TITLE)] = CdmUtils.Nz(nomRef.getTitleCache());
842 }else{
843 csvLine[table.getIndex(CdmLightExportTable.FULL_TITLE)] = CdmUtils.Nz(nomRef.getTitle());
844 }
845 TeamOrPersonBase<?> author = nomRef.getAuthorship();
846 if (author != null ){
847 csvLine[table.getIndex(CdmLightExportTable.ABBREV_REF_AUTHOR)] = CdmUtils.Nz(author.getNomenclaturalTitle());
848 csvLine[table.getIndex(CdmLightExportTable.FULL_REF_AUTHOR)] = CdmUtils.Nz(author.getTitleCache());
849 }else{
850 csvLine[table.getIndex(CdmLightExportTable.ABBREV_REF_AUTHOR)] = "";
851 csvLine[table.getIndex(CdmLightExportTable.FULL_REF_AUTHOR)] = "";
852 }
853
854 }
855 }else{
856 csvLine[table.getIndex(CdmLightExportTable.PUBLICATION_TYPE)] = "";
857 }
858
859
860
861 /*
862 * Collation
863
864 Detail
865
866
867 TitlePageYear
868 */
869 Set<TaxonNameDescription> descriptions = name.getDescriptions();
870 String protologueUriString = extractURIs(state, descriptions, Feature.PROTOLOGUE());
871
872 csvLine[table.getIndex(CdmLightExportTable.PROTOLOGUE_URI)] = protologueUriString;
873
874 if (name.getStatus() == null || name.getStatus().isEmpty()){
875 csvLine[table.getIndex(CdmLightExportTable.NOM_STATUS)] = "";
876 csvLine[table.getIndex(CdmLightExportTable.NOM_STATUS_ABBREV)] = "";
877 }else{
878
879 String statusStringAbbrev = extractStatusString(state, name, true);
880 String statusString = extractStatusString(state, name, false);
881
882 csvLine[table.getIndex(CdmLightExportTable.NOM_STATUS)] = statusString.trim();
883 csvLine[table.getIndex(CdmLightExportTable.NOM_STATUS_ABBREV)] = statusStringAbbrev.trim();
884 }
885
886 HomotypicalGroup group =name.getHomotypicalGroup();
887
888 if (state.getHomotypicalGroupFromStore(group.getId()) == null){
889 handleHomotypicalGroup(state, group);
890 }
891 csvLine[table.getIndex(CdmLightExportTable.HOMOTYPIC_GROUP_FK)] = getId(state, group);
892 List<TaxonName> typifiedNames = new ArrayList<>();
893 typifiedNames.addAll(group.getTypifiedNames());
894 Collections.sort(typifiedNames, new HomotypicalGroupNameComparator(null, true));
895 Integer seqNumber= typifiedNames.indexOf(name);
896 csvLine[table.getIndex(CdmLightExportTable.HOMOTYPIC_GROUP_SEQ)] = String.valueOf(seqNumber);
897 state.getProcessor().put(table, name, csvLine);
898
899 /*
900 *
901 Tropicos_ID
902 IPNI_ID
903
904
905 InfragenericRank
906
907
908 InfraspecificRank
909 Collation
910 Volume (Issue)
911 Detail
912 DatePublished
913 YearPublished
914 TitlePageYear
915
916
917
918 HomotypicGroupSequenceNumber
919
920
921 *
922 */
923 } catch (Exception e) {
924 state.getResult().addException(e, "An unexpected error occurred when handling synonym " +
925 cdmBaseStr(name) + ": " + e.getMessage());
926 }
927 }
928
929 /**
930 * @return
931 */
932 private String createCollatation(TaxonName name) {
933 String collation = "";
934 if (name.getNomenclaturalReference() != null){
935 Reference ref = (Reference) name.getNomenclaturalReference();
936 collation = getVolume(ref);
937 }
938 if (name.getNomenclaturalMicroReference() != null){
939 if (!StringUtils.isBlank(collation)){
940 collation += ":";
941 }
942 collation +=name.getNomenclaturalMicroReference();
943 }
944
945 return collation;
946 }
947
948 /**
949 * @param nomenclaturalReference
950 * @return
951 */
952 private String getVolume(Reference reference) {
953 if (reference.getVolume() != null){
954 return reference.getVolume();
955 }else if (reference.getInReference() != null){
956 if (reference.getInReference().getVolume() != null){
957 return reference.getInReference().getVolume();
958 }
959 }
960 return null;
961 }
962
963 /**
964 * @param state
965 * @param name
966 */
967 private void handleIdentifier(CdmLightExportState state, TaxonName name) {
968 CdmLightExportTable table = CdmLightExportTable.IDENTIFIER;
969 String[] csvLine;
970 try {
971 Set<String> IPNIidentifiers = name.getIdentifiers(DefinedTerm.IPNI_NAME_IDENTIFIER());
972 Set<String> tropicosIdentifiers = name.getIdentifiers(DefinedTerm.TROPICOS_NAME_IDENTIFIER());
973 Set<String> WFOIdentifiers = name.getIdentifiers(DefinedTerm.uuidWfoNameIdentifier);
974 if (!IPNIidentifiers.isEmpty()){
975 csvLine = new String[table.getSize()];
976 csvLine[table.getIndex(CdmLightExportTable.NAME_FK)] = getId( state, name);
977 csvLine[table.getIndex(CdmLightExportTable.IDENTIFIER_TYPE)] = IPNI_NAME_IDENTIFIER;
978 csvLine[table.getIndex(CdmLightExportTable.IDENTIFIER_IDS)] = extractIdentifier(IPNIidentifiers);
979 state.getProcessor().put(table, name, csvLine);
980 }
981 if (!tropicosIdentifiers.isEmpty()){
982 csvLine = new String[table.getSize()];
983 csvLine[table.getIndex(CdmLightExportTable.NAME_FK)] = getId( state, name);
984 csvLine[table.getIndex(CdmLightExportTable.IDENTIFIER_TYPE)] = TROPICOS_NAME_IDENTIFIER;
985 csvLine[table.getIndex(CdmLightExportTable.IDENTIFIER_IDS)] = extractIdentifier(tropicosIdentifiers);
986 state.getProcessor().put(table, name, csvLine);
987 }
988 if (!WFOIdentifiers.isEmpty()){
989 csvLine = new String[table.getSize()];
990 csvLine[table.getIndex(CdmLightExportTable.NAME_FK)] = getId( state, name);
991 csvLine[table.getIndex(CdmLightExportTable.IDENTIFIER_TYPE)] = WFO_NAME_IDENTIFIER;
992 csvLine[table.getIndex(CdmLightExportTable.IDENTIFIER_IDS)] = extractIdentifier(WFOIdentifiers);
993 state.getProcessor().put(table, name, csvLine);
994 }
995 } catch (Exception e) {
996 state.getResult().addException(e, "An unexpected error occurred when handling identifiers for " +
997 cdmBaseStr(name) + ": " + e.getMessage());
998
999 }
1000 }
1001
1002 /**
1003 * @param tropicosIdentifiers
1004 */
1005 private String extractIdentifier(Set<String> identifierSet) {
1006
1007 String identifierString = "";
1008 for (String identifier: identifierSet){
1009 if (!StringUtils.isBlank(identifierString)){
1010 identifierString += ", ";
1011 }
1012 identifierString += identifier;
1013 }
1014
1015 return identifierString;
1016 }
1017
1018 /**
1019 * @param state
1020 * @param descriptions
1021 * @return
1022 */
1023 private String extractURIs(CdmLightExportState state,
1024 Set<? extends DescriptionBase<?>> descriptionsSet, Feature feature) {
1025 String mediaUriString = "";
1026 SpecimenDescription specimenDescription;
1027 TaxonDescription taxonDescription;
1028 TaxonNameDescription nameDescription;
1029 Set<DescriptionElementBase> elements = new HashSet<>();
1030 for (DescriptionBase<?> description : descriptionsSet){
1031 try {
1032 if (!description.getElements().isEmpty()){
1033 if (description instanceof SpecimenDescription){
1034 specimenDescription = (SpecimenDescription)description;
1035 elements = specimenDescription.getElements();
1036 }else if (description instanceof TaxonDescription){
1037 taxonDescription = (TaxonDescription) description;
1038 elements = taxonDescription.getElements();
1039 } else if (description instanceof TaxonNameDescription){
1040 nameDescription = (TaxonNameDescription) description;
1041 elements = nameDescription.getElements();
1042 }
1043
1044 for (DescriptionElementBase element : elements){
1045 Feature entityFeature = HibernateProxyHelper.deproxy(element.getFeature());
1046 if (entityFeature.equals(feature)){
1047 if (!element.getMedia().isEmpty()){
1048 List<Media> media = element.getMedia();
1049 for (Media mediaElement: media){
1050 Iterator<MediaRepresentation> it = mediaElement.getRepresentations().iterator();
1051 mediaUriString = extractMediaUris(it);
1052 }
1053 }
1054 }
1055 }
1056 }
1057 } catch (Exception e) {
1058 state.getResult().addException(e, "An unexpected error occurred when extracting media URIs for " +
1059 cdmBaseStr(description) + ": " + e.getMessage());
1060 }
1061 }
1062 return mediaUriString;
1063 }
1064
1065 /**
1066 * @param state
1067 * @param basionymAuthorship
1068 */
1069 private void handleAuthor(CdmLightExportState state, TeamOrPersonBase<?> author) {
1070 try {
1071 if (state.getAuthorFromStore(author.getId()) != null){
1072 return;
1073 }
1074 state.addAuthorToStore(author);
1075 CdmLightExportTable table = CdmLightExportTable.NOMENCLATURAL_AUTHOR;
1076 String[] csvLine = new String[table.getSize()];
1077 CdmLightExportTable tableAuthorRel = CdmLightExportTable.NOMENCLATURAL_AUTHOR_TEAM_RELATION;
1078 String[] csvLineRel = new String[tableAuthorRel.getSize()];
1079 String[] csvLineMember = new String[table.getSize()];
1080 csvLine[table.getIndex(CdmLightExportTable.AUTHOR_ID)] = getId(state, author);
1081 csvLine[table.getIndex(CdmLightExportTable.ABBREV_AUTHOR)] = author.getNomenclaturalTitle();
1082 csvLine[table.getIndex(CdmLightExportTable.AUTHOR_TITLE)] = author.getTitleCache();
1083 author = HibernateProxyHelper.deproxy(author);
1084 if (author instanceof Person){
1085 Person authorPerson = (Person)author;
1086 csvLine[table.getIndex(CdmLightExportTable.AUTHOR_FIRST_NAME)] = authorPerson.getFirstname();
1087 csvLine[table.getIndex(CdmLightExportTable.AUTHOR_LASTNAME)] = authorPerson.getLastname();
1088 csvLine[table.getIndex(CdmLightExportTable.AUTHOR_PREFIX)] = authorPerson.getPrefix();
1089 csvLine[table.getIndex(CdmLightExportTable.AUTHOR_SUFFIX)] = authorPerson.getSuffix();
1090 } else{
1091 // create an entry in rel table and all members in author table, check whether the team members already in author table
1092
1093 Team authorTeam = (Team)author;
1094 int index = 0;
1095 for (Person member: authorTeam.getTeamMembers()){
1096 csvLineRel = new String[tableAuthorRel.getSize()];
1097 csvLineRel[tableAuthorRel.getIndex(CdmLightExportTable.AUTHOR_TEAM_FK)] = getId(state, authorTeam);
1098 csvLineRel[tableAuthorRel.getIndex(CdmLightExportTable.AUTHOR_FK)] = getId(state, member);
1099 csvLineRel[tableAuthorRel.getIndex(CdmLightExportTable.AUTHOR_TEAM_SEQ_NUMBER)] = String.valueOf(index);
1100 state.getProcessor().put(tableAuthorRel, authorTeam.getId() +":" +member.getId(), csvLineRel);
1101
1102 if (state.getAuthorFromStore(member.getId()) == null){
1103 state.addAuthorToStore(member);
1104 csvLineMember = new String[table.getSize()];
1105 csvLineMember[table.getIndex(CdmLightExportTable.AUTHOR_ID)] = getId(state, member);
1106 csvLineMember[table.getIndex(CdmLightExportTable.ABBREV_AUTHOR)] = member.getNomenclaturalTitle();
1107 csvLineMember[table.getIndex(CdmLightExportTable.AUTHOR_TITLE)] = member.getTitleCache();
1108 csvLineMember[table.getIndex(CdmLightExportTable.AUTHOR_FIRST_NAME)] = member.getFirstname();
1109 csvLineMember[table.getIndex(CdmLightExportTable.AUTHOR_LASTNAME)] = member.getLastname();
1110 csvLineMember[table.getIndex(CdmLightExportTable.AUTHOR_PREFIX)] = member.getPrefix();
1111 csvLineMember[table.getIndex(CdmLightExportTable.AUTHOR_SUFFIX)] = member.getSuffix();
1112 state.getProcessor().put(table, member, csvLineMember);
1113 }
1114 index++;
1115
1116 }
1117 }
1118 state.getProcessor().put(table, author, csvLine);
1119 } catch (Exception e) {
1120 state.getResult().addException(e, "An unexpected error occurred when handling author " +
1121 cdmBaseStr(author) + ": " + e.getMessage());
1122 }
1123 }
1124
1125 /**
1126 * @param state
1127 * @param name
1128 * @param statusString
1129 * @return
1130 */
1131 private String extractStatusString(CdmLightExportState state, TaxonName name, boolean abbrev) {
1132 try {
1133 Set<NomenclaturalStatus> status = name.getStatus();
1134 if (status.isEmpty()){
1135 return "";
1136 }
1137 String statusString = "";
1138 for (NomenclaturalStatus nameStatus: status){
1139 if (nameStatus != null){
1140 if (abbrev){
1141 if (nameStatus.getType() != null){
1142 statusString += nameStatus.getType().getIdInVocabulary();
1143 }
1144 }else{
1145 if (nameStatus.getType() != null){
1146 statusString += nameStatus.getType().getTitleCache();
1147 }
1148 }
1149 if (!abbrev){
1150
1151 if (nameStatus.getRuleConsidered() != null && !StringUtils.isBlank(nameStatus.getRuleConsidered())){
1152 statusString += " " + nameStatus.getRuleConsidered();
1153 }
1154 if (nameStatus.getCitation() != null){
1155 statusString += " " + nameStatus.getCitation().getTitleCache();
1156 }
1157 if (nameStatus.getCitationMicroReference() != null && !StringUtils.isBlank(nameStatus.getCitationMicroReference())){
1158 statusString += " " + nameStatus.getCitationMicroReference();
1159 }
1160 }
1161 statusString += " ";
1162 }
1163 }
1164 return statusString;
1165 } catch (Exception e) {
1166 state.getResult().addException(e, "An unexpected error occurred when extracting status string for " +
1167 cdmBaseStr(name) + ": " + e.getMessage());
1168 return "";
1169 }
1170 }
1171
1172 /**
1173 * @param group
1174 */
1175 private void handleHomotypicalGroup(CdmLightExportState state, HomotypicalGroup group) {
1176 try {
1177 state.addHomotypicalGroupToStore(group);
1178 CdmLightExportTable table = CdmLightExportTable.HOMOTYPIC_GROUP;
1179 String[] csvLine = new String[table.getSize()];
1180
1181 csvLine[table.getIndex(CdmLightExportTable.HOMOTYPIC_GROUP_ID)] = getId(state, group);
1182 List<TaxonName> typifiedNames = new ArrayList<>();
1183 typifiedNames.addAll(group.getTypifiedNames());
1184 Collections.sort(typifiedNames, new HomotypicalGroupNameComparator(null, true));
1185 String typifiedNamesString = "";
1186 for (TaxonName name: typifiedNames){
1187 //Concatenated output string for homotypic group (names and citations) + status + some name relations (e.g. “non”)
1188 //TODO: nameRelations, which and how to display
1189
1190
1191 typifiedNamesString += name.getTitleCache()+ extractStatusString(state, name, true) + "; ";
1192 }
1193 typifiedNamesString = typifiedNamesString.substring(0, typifiedNamesString.length()-2);
1194 if (typifiedNamesString != null){
1195 csvLine[table.getIndex(CdmLightExportTable.HOMOTYPIC_GROUP_STRING)] = typifiedNamesString.trim();
1196 }else{
1197 csvLine[table.getIndex(CdmLightExportTable.HOMOTYPIC_GROUP_STRING)] = "";
1198 }
1199 Set<TypeDesignationBase> typeDesigantions = group.getTypeDesignations();
1200 List<TypeDesignationBase> designationList = new ArrayList<>();
1201 designationList.addAll(typeDesigantions);
1202 Collections.sort(designationList, new TypeComparator());
1203 StringBuffer typeDesignationString = new StringBuffer();
1204 for (TypeDesignationBase typeDesignation: typeDesigantions){
1205 if (typeDesignation != null && typeDesignation.getTypeStatus() != null){
1206 typeDesignationString.append(typeDesignation.getTypeStatus().getTitleCache() + ": ");
1207 }
1208 if (typeDesignation instanceof SpecimenTypeDesignation){
1209 if (((SpecimenTypeDesignation)typeDesignation).getTypeSpecimen() != null){
1210 typeDesignationString.append(((SpecimenTypeDesignation)typeDesignation).getTypeSpecimen().getTitleCache());
1211 handleSpecimen(state, ((SpecimenTypeDesignation)typeDesignation).getTypeSpecimen());
1212 }
1213 }else{
1214 if (((NameTypeDesignation)typeDesignation).getTypeName() != null){
1215 typeDesignationString.append(((NameTypeDesignation)typeDesignation).getTypeName().getTitleCache());
1216 }
1217 }
1218 if(typeDesignation.getCitation() != null ){
1219 typeDesignationString.append(", "+typeDesignation.getCitation().getTitleCache());
1220 }
1221 //TODO...
1222 /*
1223 * Sortierung:
1224 1. Status der Typen: a) holo, lecto, neo, syn, b) epi, paralecto, c) para (wenn überhaupt) – die jeweiligen iso immer direct mit dazu
1225 2. Land
1226 3. Sammler
1227 4. Nummer
1228
1229 Aufbau der Typusinformationen:
1230 Land: Lokalität mit Höhe und Koordinaten; Datum; Sammler Nummer (Herbar/Barcode, Typusart; Herbar/Barcode, Typusart …)
1231
1232 */
1233 }
1234 String typeDesignations = typeDesignationString.toString();
1235 if (typeDesignations != null){
1236 csvLine[table.getIndex(CdmLightExportTable.TYPE_STRING)] = typeDesignations;
1237 }else{
1238 csvLine[table.getIndex(CdmLightExportTable.TYPE_STRING)] = "";
1239 }
1240 state.getProcessor().put(table, String.valueOf(group.getId()), csvLine);
1241 } catch (Exception e) {
1242 state.getResult().addException(e, "An unexpected error occurred when handling homotypic group " +
1243 cdmBaseStr(group) + ": " + e.getMessage());
1244 }
1245 }
1246
1247 /**
1248 * @param name
1249 * @return
1250 */
1251 private String getTropicosTitleCache(CdmLightExportState state, TaxonName name) {
1252 try {
1253 String basionymStart = "(";
1254 String basionymEnd = ") ";
1255 String exAuthorSeperator = " ex ";
1256 TeamOrPersonBase<?> combinationAuthor = name.getCombinationAuthorship();
1257 TeamOrPersonBase<?> exCombinationAuthor = name.getExCombinationAuthorship();
1258 TeamOrPersonBase<?> basionymAuthor = name.getBasionymAuthorship();
1259 TeamOrPersonBase<?> exBasionymAuthor = name.getExBasionymAuthorship();
1260
1261 String combinationAuthorString = "";
1262 if (combinationAuthor != null){
1263 combinationAuthor = HibernateProxyHelper.deproxy(combinationAuthor);
1264 if (combinationAuthor instanceof Team){
1265 combinationAuthorString = createTropicosTeamTitle(combinationAuthor);
1266 }else{
1267 Person person = HibernateProxyHelper.deproxy(combinationAuthor, Person.class);
1268 combinationAuthorString = createTropicosAuthorString(person);
1269 }
1270 }
1271 String exCombinationAuthorString = "";
1272 if (exCombinationAuthor != null){
1273 exCombinationAuthor = HibernateProxyHelper.deproxy(exCombinationAuthor);
1274 if (exCombinationAuthor instanceof Team){
1275 exCombinationAuthorString = createTropicosTeamTitle(exCombinationAuthor);
1276 }else{
1277 Person person = HibernateProxyHelper.deproxy(exCombinationAuthor, Person.class);
1278 exCombinationAuthorString = createTropicosAuthorString(person);
1279 }
1280 }
1281
1282 String basionymAuthorString = "";
1283 if (basionymAuthor != null){
1284 basionymAuthor = HibernateProxyHelper.deproxy(basionymAuthor);
1285 if (basionymAuthor instanceof Team){
1286 basionymAuthorString = createTropicosTeamTitle(basionymAuthor);
1287 }else{
1288 Person person = HibernateProxyHelper.deproxy(basionymAuthor, Person.class);
1289 basionymAuthorString = createTropicosAuthorString(person);
1290 }
1291 }
1292
1293 String exBasionymAuthorString = "";
1294
1295 if (exBasionymAuthor != null){
1296 exBasionymAuthor = HibernateProxyHelper.deproxy(exBasionymAuthor);
1297 if (exBasionymAuthor instanceof Team){
1298 exBasionymAuthorString = createTropicosTeamTitle(exBasionymAuthor);
1299
1300 }else{
1301 Person person = HibernateProxyHelper.deproxy(exBasionymAuthor, Person.class);
1302 exBasionymAuthorString = createTropicosAuthorString(person);
1303 }
1304 }
1305 String completeAuthorString = name.getNameCache() + " ";
1306
1307 completeAuthorString += (!CdmUtils.isBlank(exBasionymAuthorString) || !CdmUtils.isBlank(basionymAuthorString)) ? basionymStart: "";
1308 completeAuthorString += (!CdmUtils.isBlank(exBasionymAuthorString)) ? (CdmUtils.Nz(exBasionymAuthorString) + exAuthorSeperator): "" ;
1309 completeAuthorString += (!CdmUtils.isBlank(basionymAuthorString))? CdmUtils.Nz(basionymAuthorString):"";
1310 completeAuthorString += (!CdmUtils.isBlank(exBasionymAuthorString) || !CdmUtils.isBlank(basionymAuthorString)) ? basionymEnd:"";
1311 completeAuthorString += (!CdmUtils.isBlank(exCombinationAuthorString)) ? (CdmUtils.Nz(exCombinationAuthorString) + exAuthorSeperator): "" ;
1312 completeAuthorString += (!CdmUtils.isBlank(combinationAuthorString))? CdmUtils.Nz(combinationAuthorString):"";
1313
1314
1315 return completeAuthorString;
1316 } catch (Exception e) {
1317 state.getResult().addException(e, "An unexpected error occurred when handling tropicos title cache for " +
1318 cdmBaseStr(name) + ": " + e.getMessage());
1319 return null;
1320 }
1321 }
1322
1323 /**
1324 * @param combinationAuthor
1325 * @return
1326 */
1327 private String createTropicosTeamTitle(TeamOrPersonBase<?> combinationAuthor) {
1328 String combinationAuthorString;
1329 Team team = HibernateProxyHelper.deproxy(combinationAuthor, Team.class);
1330 Team tempTeam = Team.NewInstance();
1331 for (Person teamMember:team.getTeamMembers()){
1332 combinationAuthorString = createTropicosAuthorString(teamMember);
1333 Person tempPerson = Person.NewTitledInstance(combinationAuthorString);
1334 tempTeam.addTeamMember(tempPerson);
1335 }
1336 combinationAuthorString = tempTeam.generateTitle();
1337 return combinationAuthorString;
1338 }
1339
1340 /**
1341 * @param teamMember
1342 */
1343 private String createTropicosAuthorString(Person teamMember) {
1344 String nomAuthorString = "";
1345 String[] splittedAuthorString = null;
1346 if (teamMember == null){
1347 return nomAuthorString;
1348 }
1349
1350 if (teamMember.getFirstname() != null){
1351 String firstNameString = teamMember.getFirstname().replaceAll("\\.", "\\. ");
1352 splittedAuthorString = firstNameString.split("\\s");
1353 for (String split: splittedAuthorString){
1354 if (!StringUtils.isBlank(split)){
1355 nomAuthorString += split.substring(0, 1);
1356 nomAuthorString += ".";
1357 }
1358 }
1359 }
1360 if (teamMember.getLastname() != null){
1361 String lastNameString = teamMember.getLastname().replaceAll("\\.", "\\. ");
1362 splittedAuthorString = lastNameString.split("\\s");
1363 for (String split: splittedAuthorString){
1364 nomAuthorString += " " +split;
1365 }
1366 }
1367 if (StringUtils.isBlank(nomAuthorString.trim())){
1368 if (teamMember.getTitleCache() != null) {
1369 String titleCacheString = teamMember.getTitleCache().replaceAll("\\.", "\\. ");
1370 splittedAuthorString = titleCacheString.split("\\s");
1371 }
1372
1373
1374 int index = 0;
1375 for (String split: splittedAuthorString){
1376 if ( index < splittedAuthorString.length-1 && (split.length()==1 || split.endsWith("."))){
1377 nomAuthorString += split;
1378 }else{
1379 nomAuthorString = nomAuthorString +" "+ split;
1380 }
1381 index++;
1382 }
1383 }
1384 return nomAuthorString.trim();
1385 }
1386
1387 /**
1388 * @param state
1389 * @param name
1390 */
1391 private void handleReference(CdmLightExportState state, Reference reference) {
1392 try {
1393 state.addReferenceToStore(reference);
1394 CdmLightExportTable table = CdmLightExportTable.REFERENCE;
1395
1396 String[] csvLine = new String[table.getSize()];
1397 csvLine[table.getIndex(CdmLightExportTable.REFERENCE_ID)] = getId(state, reference);
1398 //TODO short citations correctly
1399 String shortCitation = createShortCitation(reference); //Should be Author(year) like in Taxon.sec
1400 csvLine[table.getIndex(CdmLightExportTable.BIBLIO_SHORT_CITATION)] = shortCitation;
1401 //TODO get preferred title
1402 csvLine[table.getIndex(CdmLightExportTable.REF_TITLE)] = reference.getTitle();
1403 csvLine[table.getIndex(CdmLightExportTable.ABBREV_REF_TITLE)] = reference.getAbbrevTitle();
1404 csvLine[table.getIndex(CdmLightExportTable.DATE_PUBLISHED)] = reference.getDatePublishedString();
1405 //TBC
1406 csvLine[table.getIndex(CdmLightExportTable.EDITION)] = reference.getEdition();
1407 csvLine[table.getIndex(CdmLightExportTable.EDITOR)] = reference.getEditor();
1408 csvLine[table.getIndex(CdmLightExportTable.ISBN)] = reference.getIsbn();
1409 csvLine[table.getIndex(CdmLightExportTable.ISSN)] = reference.getIssn();
1410 csvLine[table.getIndex(CdmLightExportTable.ORGANISATION)] = reference.getOrganization();
1411 csvLine[table.getIndex(CdmLightExportTable.PAGES)] = reference.getPages();
1412 csvLine[table.getIndex(CdmLightExportTable.PLACE_PUBLISHED)] = reference.getPlacePublished();
1413 csvLine[table.getIndex(CdmLightExportTable.PUBLISHER)] = reference.getPublisher();
1414 csvLine[table.getIndex(CdmLightExportTable.REF_ABSTRACT)] = reference.getReferenceAbstract();
1415 csvLine[table.getIndex(CdmLightExportTable.SERIES_PART)] = reference.getSeriesPart();
1416 csvLine[table.getIndex(CdmLightExportTable.VOLUME)] = reference.getVolume();
1417 csvLine[table.getIndex(CdmLightExportTable.YEAR)] = reference.getYear();
1418 if ( reference.getAuthorship() != null){
1419 csvLine[table.getIndex(CdmLightExportTable.AUTHORSHIP_TITLE)] = reference.getAuthorship().getTitleCache();
1420 csvLine[table.getIndex(CdmLightExportTable.AUTHOR_FK)] = getId(state,reference.getAuthorship());
1421 }
1422
1423 csvLine[table.getIndex(CdmLightExportTable.IN_REFERENCE)] = getId(state, reference.getInReference());
1424 if (reference.getInReference() != null && state.getReferenceFromStore(reference.getInReference().getId()) == null){
1425 handleReference(state, reference.getInReference());
1426 }
1427 if ( reference.getInstitution() != null){ csvLine[table.getIndex(CdmLightExportTable.INSTITUTION)] = reference.getInstitution().getTitleCache();}
1428 if ( reference.getLsid() != null){ csvLine[table.getIndex(CdmLightExportTable.LSID)] = reference.getLsid().getLsid();}
1429 if ( reference.getSchool() != null){ csvLine[table.getIndex(CdmLightExportTable.SCHOOL)] = reference.getSchool().getTitleCache();}
1430 if ( reference.getUri() != null){ csvLine[table.getIndex(CdmLightExportTable.URI)] = reference.getUri().toString();}
1431 csvLine[table.getIndex(CdmLightExportTable.REF_TYPE)] = reference.getType().getKey();
1432
1433 state.getProcessor().put(table, reference, csvLine);
1434 } catch (Exception e) {
1435 state.getResult().addException(e, "An unexpected error occurred when handling reference " +
1436 cdmBaseStr(reference) + ": " + e.getMessage());
1437 }
1438
1439 }
1440
1441
1442 /**
1443 * @param reference
1444 * @return
1445 */
1446 private String createShortCitation(Reference reference) {
1447 TeamOrPersonBase<?> authorship = reference.getAuthorship();
1448 String shortCitation = "";
1449 if (authorship == null) {
1450 return null;
1451 }
1452 authorship = HibernateProxyHelper.deproxy(authorship);
1453 if (authorship instanceof Person){ shortCitation = ((Person)authorship).getLastname();}
1454 else if (authorship instanceof Team){
1455
1456 Team authorTeam = HibernateProxyHelper.deproxy(authorship, Team.class);
1457 int index = 0;
1458
1459 for (Person teamMember : authorTeam.getTeamMembers()){
1460 index++;
1461 String concat = concatString(authorTeam, authorTeam.getTeamMembers(), index);
1462 shortCitation += concat + teamMember.getLastname();
1463 }
1464
1465 }
1466 if (reference.getYear() != null){
1467 shortCitation = shortCitation + " (" + reference.getYear() + ")";
1468 }
1469 return shortCitation;
1470 }
1471
1472 private static String concatString(Team team, List<Person> teamMembers, int i) {
1473 String concat;
1474 if (i <= 1){
1475 concat = "";
1476 }else if (i < teamMembers.size() || ( team.isHasMoreMembers() && i == teamMembers.size())){
1477 concat = STD_TEAM_CONCATINATION;
1478 }else{
1479 concat = FINAL_TEAM_CONCATINATION;
1480 }
1481 return concat;
1482 }
1483
1484 /*
1485 * TypeDesignation table
1486 * Specimen_Fk
1487 * EditName_Fk
1488 * TypeVerbatimCitation
1489 * TypeCategory
1490 * TypeDesignatedByString
1491 * TypeDesignatedByRef_Fk
1492 */
1493
1494 private void handleSpecimenTypeDesignations(CdmLightExportState state, TaxonName name){
1495 try {
1496 Set<SpecimenTypeDesignation> typeDesignations = name.getSpecimenTypeDesignations();
1497 CdmLightExportTable table = CdmLightExportTable.TYPE_DESIGNATION;
1498 String nameId = getId(state, name);
1499 String[] csvLine = new String[table.getSize()];
1500 for (SpecimenTypeDesignation specimenType: typeDesignations){
1501 csvLine = new String[table.getSize()];
1502 DerivedUnit specimen = specimenType.getTypeSpecimen();
1503 if (state.getSpecimenFromStore(specimen.getId()) == null){
1504 handleSpecimen(state, specimen);
1505 }
1506 csvLine[table.getIndex(CdmLightExportTable.SPECIMEN_FK)] = getId(state, specimenType.getTypeSpecimen());
1507 csvLine[table.getIndex(CdmLightExportTable.NAME_FK)] = nameId;
1508 csvLine[table.getIndex(CdmLightExportTable.TYPE_VERBATIM_CITATION)] = specimenType.getTypeSpecimen().generateTitle();
1509 //TODO: add link to existing Vorcabulary
1510 csvLine[table.getIndex(CdmLightExportTable.TYPE_CATEGORY)] = "";
1511 csvLine[table.getIndex(CdmLightExportTable.TYPE_DESIGNATED_BY_STRING)] = specimenType.getCitation().getTitleCache();
1512 csvLine[table.getIndex(CdmLightExportTable.TYPE_DESIGNATED_BY_REF_FK)] = getId(state, specimenType.getCitation());
1513 }
1514 } catch (Exception e) {
1515 state.getResult().addException(e, "An unexpected error occurred when handling specimen type designations for " +
1516 cdmBaseStr(name) + ": " + e.getMessage());
1517 }
1518 }
1519
1520 /**
1521 * @param state
1522 * @param specimen
1523 */
1524 private void handleSpecimen(CdmLightExportState state, SpecimenOrObservationBase specimen) {
1525 try {
1526 state.addSpecimenToStore(specimen);
1527 CdmLightExportTable table = CdmLightExportTable.SPECIMEN;
1528 String specimenId = getId(state, specimen);
1529 String[] csvLine = new String[table.getSize()];
1530
1531 csvLine[table.getIndex(CdmLightExportTable.SPECIMEN_ID)] = specimenId;
1532 csvLine[table.getIndex(CdmLightExportTable.SPECIMEN_CITATION)] = specimen.getTitleCache();
1533 csvLine[table.getIndex(CdmLightExportTable.SPECIMEN_IMAGE_URIS)] = extractURIs(state, specimen.getDescriptions(), Feature.IMAGE());
1534 if (specimen instanceof DerivedUnit){
1535 DerivedUnit derivedUnit = (DerivedUnit)specimen;
1536 if (derivedUnit.getCollection() != null){ csvLine[table.getIndex(CdmLightExportTable.HERBARIUM_ABBREV)] = derivedUnit.getCollection().getCode();}
1537
1538 if (specimen instanceof MediaSpecimen){
1539 MediaSpecimen mediaSpecimen = (MediaSpecimen) specimen;
1540 Iterator<MediaRepresentation> it = mediaSpecimen.getMediaSpecimen().getRepresentations().iterator();
1541 String mediaUris = extractMediaUris(it);
1542 csvLine[table.getIndex(CdmLightExportTable.MEDIA_SPECIMEN_URL)] = mediaUris;
1543
1544 }
1545
1546 if (derivedUnit.getDerivedFrom() != null){
1547 for (SpecimenOrObservationBase<?> original: derivedUnit.getDerivedFrom().getOriginals()){
1548 //TODO: What to do if there are more then one FieldUnit??
1549 if (original instanceof FieldUnit){
1550 FieldUnit fieldUnit = (FieldUnit)original;
1551 csvLine[table.getIndex(CdmLightExportTable.COLLECTOR_NUMBER)] = fieldUnit.getFieldNumber();
1552
1553 GatheringEvent gathering = fieldUnit.getGatheringEvent();
1554 if (gathering != null){
1555 if (gathering.getLocality() != null){ csvLine[table.getIndex(CdmLightExportTable.LOCALITY)] = gathering.getLocality().getText();}
1556 if (gathering.getCountry() != null){csvLine[table.getIndex(CdmLightExportTable.COUNTRY)] = gathering.getCountry().getLabel();}
1557 csvLine[table.getIndex(CdmLightExportTable.COLLECTOR_STRING)] = createCollectorString(state, gathering, fieldUnit);
1558 addCollectingAreas(state, gathering);
1559 if (gathering.getGatheringDate() != null){csvLine[table.getIndex(CdmLightExportTable.COLLECTION_DATE)] = gathering.getGatheringDate().toString();}
1560 if (!gathering.getCollectingAreas().isEmpty()){
1561 int index = 0;
1562 csvLine[table.getIndex(CdmLightExportTable.FURTHER_AREAS)] = "0";
1563 for (NamedArea area: gathering.getCollectingAreas()){
1564 if (index == 0){
1565 csvLine[table.getIndex(CdmLightExportTable.AREA_CATEGORY1)] = area.getTermType().getKey();
1566 csvLine[table.getIndex(CdmLightExportTable.AREA_NAME1)] = area.getLabel();
1567 }
1568 if (index == 1){
1569 csvLine[table.getIndex(CdmLightExportTable.AREA_CATEGORY2)] = area.getTermType().getKey();
1570 csvLine[table.getIndex(CdmLightExportTable.AREA_NAME2)] = area.getLabel();
1571 }
1572 if (index == 2){
1573 csvLine[table.getIndex(CdmLightExportTable.AREA_CATEGORY3)] = area.getTermType().getKey();
1574 csvLine[table.getIndex(CdmLightExportTable.AREA_NAME3)] = area.getLabel();
1575 }
1576 if (index == 3){
1577 csvLine[table.getIndex(CdmLightExportTable.FURTHER_AREAS)] = "1";
1578 break;
1579 }
1580 index++;
1581 }
1582 }
1583 }
1584 }
1585 }
1586 }
1587 }
1588
1589 state.getProcessor().put(table, specimen, csvLine);
1590 } catch (Exception e) {
1591 state.getResult().addException(e, "An unexpected error occurred when handling specimen " +
1592 cdmBaseStr(specimen) + ": " + e.getMessage());
1593 }
1594 }
1595
1596 /**
1597 * @param it
1598 */
1599 private String extractMediaUris(Iterator<MediaRepresentation> it) {
1600
1601 String mediaUriString = "";
1602 boolean first = true;
1603 while(it.hasNext()){
1604 MediaRepresentation rep = it.next();
1605 List<MediaRepresentationPart> parts = rep.getParts();
1606 for (MediaRepresentationPart part: parts){
1607 if (first){
1608 if (part.getUri() != null){
1609 mediaUriString += part.getUri().toString();
1610 first = false;
1611 }
1612 }else{
1613 if (part.getUri() != null){
1614 mediaUriString += ", " +part.getUri().toString();
1615 }
1616 }
1617 }
1618 }
1619
1620 return mediaUriString;
1621 }
1622
1623 /**
1624 * @param state
1625 * @param gathering
1626 */
1627 private void addCollectingAreas(CdmLightExportState state, GatheringEvent gathering) {
1628 // TODO implement !!!
1629
1630 if (!gathering.getCollectingAreas().isEmpty()){
1631 state.getResult().addWarning("Collecting areas not yet implemented but gathering " +
1632 cdmBaseStr(gathering) + " has collecting areas.");
1633 }
1634
1635 }
1636
1637 /**
1638 * @param gathering
1639 * @return
1640 */
1641 private String createCollectorString(CdmLightExportState state, GatheringEvent gathering, FieldUnit fieldUnit) {
1642 try {
1643 String collectorString = "";
1644 AgentBase<?> collectorA = CdmBase.deproxy(gathering.getCollector());
1645 if (gathering.getCollector() != null){
1646 if (collectorA instanceof TeamOrPersonBase
1647 && state.getConfig().isHighLightPrimaryCollector()){
1648
1649 Person primaryCollector = fieldUnit.getPrimaryCollector();
1650 if (collectorA instanceof Team){
1651 Team collectorTeam = (Team)collectorA;
1652 boolean isFirst = true;
1653 for (Person member: collectorTeam.getTeamMembers()){
1654 if (!isFirst){
1655 collectorString += "; ";
1656 }
1657 if (member.equals(primaryCollector)){
1658 //highlight
1659 collectorString += "<b>" + member.getTitleCache() + "</b>";
1660 }else{
1661 collectorString += member.getTitleCache();
1662 }
1663 }
1664 }
1665 } else{
1666 collectorString = collectorA.getTitleCache();
1667 }
1668 }
1669 return collectorString;
1670 } catch (Exception e) {
1671 state.getResult().addException(e, "An unexpected error occurred when creating collector string for " +
1672 cdmBaseStr(fieldUnit) + ": " + e.getMessage());
1673 return "";
1674 }
1675 }
1676
1677
1678 /**
1679 * Returns a string representation of the {@link CdmBase cdmBase} object
1680 * for result messages.
1681 */
1682 private String cdmBaseStr(CdmBase cdmBase) {
1683 if (cdmBase == null){
1684 return "-no object available-";
1685 }else{
1686 return cdmBase.getClass().getSimpleName() + ": " + cdmBase.getUuid();
1687 }
1688 }
1689
1690 /**
1691 * {@inheritDoc}
1692 */
1693 @Override
1694 protected boolean doCheck(CdmLightExportState state) {
1695 return false;
1696 }
1697
1698 /**
1699 * {@inheritDoc}
1700 */
1701 @Override
1702 protected boolean isIgnore(CdmLightExportState state) {
1703 return false;
1704 }
1705
1706 }