Project

General

Profile

Download (57.5 KB) Statistics
| Branch: | Tag: | Revision:
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.outputmodel;
10

    
11
import java.util.ArrayList;
12
import java.util.Collections;
13
import java.util.HashSet;
14
import java.util.Iterator;
15
import java.util.List;
16
import java.util.Set;
17
import java.util.UUID;
18

    
19
import org.apache.commons.lang3.StringUtils;
20
import org.springframework.stereotype.Component;
21

    
22
import eu.etaxonomy.cdm.common.CdmUtils;
23
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
24
import eu.etaxonomy.cdm.io.common.CdmExportBase;
25
import eu.etaxonomy.cdm.io.common.ExportResult.ExportResultState;
26
import eu.etaxonomy.cdm.io.common.ICdmExport;
27
import eu.etaxonomy.cdm.io.common.mapping.out.IExportTransformer;
28
import eu.etaxonomy.cdm.model.agent.Person;
29
import eu.etaxonomy.cdm.model.agent.Team;
30
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
31
import eu.etaxonomy.cdm.model.common.CdmBase;
32
import eu.etaxonomy.cdm.model.common.DefinedTerm;
33
import eu.etaxonomy.cdm.model.common.ICdmBase;
34
import eu.etaxonomy.cdm.model.common.IIdentifiableEntity;
35
import eu.etaxonomy.cdm.model.common.Language;
36
import eu.etaxonomy.cdm.model.common.LanguageString;
37
import eu.etaxonomy.cdm.model.description.CommonTaxonName;
38
import eu.etaxonomy.cdm.model.description.DescriptionBase;
39
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
40
import eu.etaxonomy.cdm.model.description.DescriptionElementSource;
41
import eu.etaxonomy.cdm.model.description.Distribution;
42
import eu.etaxonomy.cdm.model.description.Feature;
43
import eu.etaxonomy.cdm.model.description.IndividualsAssociation;
44
import eu.etaxonomy.cdm.model.description.SpecimenDescription;
45
import eu.etaxonomy.cdm.model.description.TaxonDescription;
46
import eu.etaxonomy.cdm.model.description.TaxonNameDescription;
47
import eu.etaxonomy.cdm.model.description.TextData;
48
import eu.etaxonomy.cdm.model.location.NamedArea;
49
import eu.etaxonomy.cdm.model.media.Media;
50
import eu.etaxonomy.cdm.model.media.MediaRepresentation;
51
import eu.etaxonomy.cdm.model.media.MediaRepresentationPart;
52
import eu.etaxonomy.cdm.model.name.HomotypicalGroup;
53
import eu.etaxonomy.cdm.model.name.HomotypicalGroupNameComparator;
54
import eu.etaxonomy.cdm.model.name.NameTypeDesignation;
55
import eu.etaxonomy.cdm.model.name.NomenclaturalStatus;
56
import eu.etaxonomy.cdm.model.name.Rank;
57
import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;
58
import eu.etaxonomy.cdm.model.name.TaxonName;
59
import eu.etaxonomy.cdm.model.name.TypeComparator;
60
import eu.etaxonomy.cdm.model.name.TypeDesignationBase;
61
import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
62
import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
63
import eu.etaxonomy.cdm.model.occurrence.GatheringEvent;
64
import eu.etaxonomy.cdm.model.occurrence.MediaSpecimen;
65
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
66
import eu.etaxonomy.cdm.model.reference.Reference;
67
import eu.etaxonomy.cdm.model.reference.ReferenceType;
68
import eu.etaxonomy.cdm.model.taxon.Classification;
69
import eu.etaxonomy.cdm.model.taxon.Synonym;
70
import eu.etaxonomy.cdm.model.taxon.Taxon;
71
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
72
import eu.etaxonomy.cdm.strategy.exceptions.UnknownCdmTypeException;
73

    
74
/**
75
 * @author k.luther
76
 * @date 15.03.2017
77
 *
78
 */
79
@Component
80
public class OutputModelClassificationExport
81
            extends CdmExportBase<OutputModelConfigurator, OutputModelExportState, IExportTransformer>
82
            implements ICdmExport<OutputModelConfigurator, OutputModelExportState>{
83

    
84

    
85
    private static final long serialVersionUID = 2518643632756927053L;
86

    
87
    public OutputModelClassificationExport() {
88
        super();
89
        this.ioName = this.getClass().getSimpleName();
90

    
91
    }
92

    
93
    /**
94
     * {@inheritDoc}
95
     */
96
    @Override
97
    protected void doInvoke(OutputModelExportState state) {
98
        OutputModelConfigurator config = state.getConfig();
99

    
100
        if (config.getClassificationUuids().isEmpty()){
101
            //TODO
102
            state.setEmptyData();
103
            return;
104
        }
105
        //TODO MetaData
106
        for (UUID classificationUuid : config.getClassificationUuids()){
107
            Classification classification = getClassificationService().find(classificationUuid);
108

    
109

    
110
            if (classification == null){
111
                String message = String.format("Classification for given classification UUID not found. No data imported for %s", classificationUuid.toString());
112
                //TODO
113
                state.getResult().addWarning(message);
114
            }else{
115
//                gtTaxonNodeService().
116
                TaxonNode root = classification.getRootNode();
117

    
118
                UUID uuid = root.getUuid();
119

    
120
                root = getTaxonNodeService().load(uuid);
121
                for (TaxonNode child : root.getChildNodes()){
122
                    handleTaxon(state, child);
123
                    //TODO progress monitor
124
                }
125
            }
126
        }
127
        state.getProcessor().createFinalResult(state);
128
    }
129

    
130
    /**
131
     * @param state
132
     * @param taxon
133
     */
134
    private void handleTaxon(OutputModelExportState state, TaxonNode taxonNode) {
135

    
136
        Taxon taxon = taxonNode.getTaxon();
137
        if (taxon == null){
138
            state.getResult().addError("There was a taxon node without a taxon: " + taxonNode.getUuid());
139
            state.getResult().setState(ExportResultState.INCOMPLETE_WITH_ERROR);
140
            System.err.println("There was a taxon node without a taxon: " + taxonNode.getUuid());
141

    
142
        }else{
143
             try{
144
                TaxonName name = taxon.getName();
145
                handleName(state, name);
146
                for (Synonym syn : taxon.getSynonyms()){
147
                    handleSynonym(state, syn);
148
                }
149

    
150

    
151
                OutputModelTable table = OutputModelTable.TAXON;
152
                String[] csvLine = new String[table.getSize()];
153

    
154
                csvLine[table.getIndex(OutputModelTable.TAXON_ID)] = getId(state, taxon);
155
                csvLine[table.getIndex(OutputModelTable.NAME_FK)] = getId(state, name);
156
                Taxon parent = (taxonNode.getParent()==null) ? null : taxonNode.getParent().getTaxon();
157
                csvLine[table.getIndex(OutputModelTable.PARENT_FK)] = getId(state, parent);
158
                csvLine[table.getIndex(OutputModelTable.SEC_REFERENCE_FK)] = getId(state, taxon.getSec());
159
                csvLine[table.getIndex(OutputModelTable.SEC_REFERENCE)] = getTitleCache(taxon.getSec());
160
                csvLine[table.getIndex(OutputModelTable.CLASSIFICATION_ID)] = getId(state, taxonNode.getClassification());
161
                csvLine[table.getIndex(OutputModelTable.CLASSIFICATION_TITLE)] = taxonNode.getClassification().getTitleCache();
162

    
163
                state.getProcessor().put(table, taxon, csvLine, state);
164
                handleDescriptions(state, taxon);
165
                 }catch(Exception e){
166
                     state.getResult().addError("An unexpected problems trying to export taxon with id " + taxon.getId() + e.getStackTrace());
167
                     e.printStackTrace();
168
                     state.getResult().setState(ExportResultState.INCOMPLETE_WITH_ERROR);
169
                 }
170
             }
171
           for (TaxonNode child: taxonNode.getChildNodes()){
172
               handleTaxon(state, child);
173
           }
174

    
175
    }
176

    
177
    /**
178
     * @param state
179
     * @param taxon
180
     */
181
    private void handleDescriptions(OutputModelExportState state, CdmBase cdmBase) {
182
        if (cdmBase instanceof Taxon){
183
            Taxon taxon = HibernateProxyHelper.deproxy(cdmBase, Taxon.class);
184
            Set<TaxonDescription> descriptions = taxon.getDescriptions();
185
            List<DescriptionElementBase> simpleFacts = new ArrayList<>();
186
            List<DescriptionElementBase> specimenFacts = new ArrayList<>();
187
            List<DescriptionElementBase> distributionFacts = new ArrayList<>();
188
            List<DescriptionElementBase> commonNameFacts = new ArrayList<>();
189
            List<DescriptionElementBase> usageFacts = new ArrayList<>();
190
            for (TaxonDescription description: descriptions){
191
                if (description.getElements() != null){
192
                    for (DescriptionElementBase element: description.getElements()){
193
                        if (element.getFeature().equals(Feature.COMMON_NAME())){
194
                            commonNameFacts.add(element);
195
                        }else if (element.getFeature().equals(Feature.DISTRIBUTION())){
196
                            distributionFacts.add(element);
197
                        }else if (element.getFeature().equals(Feature.SPECIMEN())){
198
                            specimenFacts.add(element);
199
                        }else{
200
                            simpleFacts.add(element);
201
                        }
202
                    }
203
                }
204
            }
205
            if (!commonNameFacts.isEmpty()){ handleCommonNameFacts(state, taxon, commonNameFacts);}
206
            if (!distributionFacts.isEmpty()){ handleDistributionFacts(state, taxon, distributionFacts);}
207
            if (!specimenFacts.isEmpty()){ handleSpecimenFacts(state, taxon, specimenFacts);}
208
            if (!simpleFacts.isEmpty()){ handleSimpleFacts(state, taxon, simpleFacts);}
209
        } else if (cdmBase instanceof TaxonName){
210
            TaxonName name = CdmBase.deproxy(cdmBase, TaxonName.class);
211
            Set<TaxonNameDescription> descriptions = name.getDescriptions();
212
            List<DescriptionElementBase> simpleFacts = new ArrayList<>();
213
            for (TaxonNameDescription description: descriptions){
214
                if (description.getElements() != null){
215
                    for (DescriptionElementBase element: description.getElements()){
216
                        if (!element.getFeature().equals(Feature.PROTOLOGUE())){
217
                            simpleFacts.add(element);
218
                            }
219
                    }
220
                }
221

    
222
             }
223
            if (!simpleFacts.isEmpty()){ handleSimpleFacts(state, cdmBase, simpleFacts);}
224
        }
225

    
226

    
227
    }
228

    
229

    
230

    
231
    /**
232
     * @param state
233
     * @param taxon
234
     * @param simpleFacts
235
     */
236
    private void handleSimpleFacts(OutputModelExportState state, CdmBase cdmBase,
237
            List<DescriptionElementBase> simpleFacts) {
238
        OutputModelTable table = OutputModelTable.SIMPLE_FACT;
239
        String[] csvLine = new String[table.getSize()];
240

    
241
        for (DescriptionElementBase element: simpleFacts){
242
            handleSource(state, element, OutputModelTable.SIMPLE_FACT);
243

    
244
            if (element instanceof TextData){
245
               TextData textData = (TextData)element;
246
               csvLine = new String[table.getSize()];
247
               csvLine[table.getIndex(OutputModelTable.FACT_ID)] = getId(state, element);
248
               if (cdmBase instanceof Taxon){
249
                   csvLine[table.getIndex(OutputModelTable.TAXON_FK)] = getId(state, cdmBase);
250
                   csvLine[table.getIndex(OutputModelTable.NAME_FK)] = "";
251
               }else if (cdmBase instanceof TaxonName){
252
                   csvLine[table.getIndex(OutputModelTable.TAXON_FK)] = "";
253
                   csvLine[table.getIndex(OutputModelTable.NAME_FK)] = getId(state, cdmBase);
254
               }
255
               csvLine[table.getIndex(OutputModelTable.FACT_CATEGORY)] = textData.getFeature().getLabel();
256

    
257
               String mediaUris = "";
258
               for (Media media: textData.getMedia()){
259
                   String mediaString = extractMediaUris(media.getRepresentations().iterator());
260
                   if (!StringUtils.isBlank(mediaString)){ mediaUris +=  mediaString + ";";}
261
                   else{state.getResult().addWarning("Empty Media object for uuid: " + cdmBase.getUuid() + " uuid of media: " + media.getUuid());}
262
               }
263
               csvLine[table.getIndex(OutputModelTable.MEDIA_URI)] = mediaUris;
264
               if (textData.getFeature().equals(Feature.CITATION())){
265
                  // csvLine[table.getIndex(OutputModelTable.TAXON_FK)] = getId(state, cdmBase);
266
                   state.getProcessor().put(table, textData, csvLine, state);
267
               }else if (!textData.getMultilanguageText().isEmpty()){
268
                       for (Language language: textData.getMultilanguageText().keySet()){
269
                           String[] csvLineLanguage = csvLine.clone();
270
                           LanguageString langString = textData.getLanguageText(language);
271

    
272
                           csvLineLanguage[table.getIndex(OutputModelTable.FACT_TEXT)] = langString.getText();
273
                           csvLineLanguage[table.getIndex(OutputModelTable.LANGUAGE)] = language.getLabel();
274
                           state.getProcessor().put(table, textData, csvLineLanguage, state);
275
                       }
276
               } else{
277

    
278
                   state.getProcessor().put(table, textData, csvLine, state);
279

    
280
               }
281
            }
282
        }
283
    }
284

    
285
    /**
286
     * @param state
287
     * @param specimenFacts
288
     */
289
    private void handleSpecimenFacts(OutputModelExportState state, Taxon taxon, List<DescriptionElementBase> specimenFacts) {
290
        OutputModelTable table = OutputModelTable.SPECIMEN_FACT;
291
        String[] csvLine = new String[table.getSize()];
292

    
293
        for (DescriptionElementBase element: specimenFacts){
294
            if (element instanceof IndividualsAssociation){
295
                IndividualsAssociation indAssociation = (IndividualsAssociation)element;
296
                csvLine[table.getIndex(OutputModelTable.FACT_ID)] = getId(state, element);
297
                handleSource(state, element, table);
298
                if (state.getSpecimenFromStore(indAssociation.getAssociatedSpecimenOrObservation().getId()) == null){
299
                    SpecimenOrObservationBase specimenBase = HibernateProxyHelper.deproxy(indAssociation.getAssociatedSpecimenOrObservation());
300

    
301
                    if (specimenBase instanceof DerivedUnit){
302
                        DerivedUnit derivedUnit = (DerivedUnit)specimenBase;
303
                        handleSpecimen(state, derivedUnit);
304
                        csvLine[table.getIndex(OutputModelTable.TAXON_FK)] = getId(state, taxon);
305
                        csvLine[table.getIndex(OutputModelTable.SPECIMEN_FK)] = getId(state, indAssociation.getAssociatedSpecimenOrObservation());
306
                        state.getProcessor().put(table, indAssociation, csvLine, state);
307
                    }else{
308
                        state.getResult().addError("The associated Specimen of taxon " + taxon.getUuid() + " is not an DerivedUnit. Could not be exported.");
309
                    }
310

    
311
                }
312

    
313
            } else{
314
                state.getResult().addError("The specimen description for the taxon " + taxon.getUuid() + " is not of type individual association. Could not be exported. UUID of the description element: " + element.getUuid());
315
            }
316
        }
317
    }
318

    
319
    /**
320
     * @param state
321
     * @param taxon
322
     * @param element
323
     */
324
    private void handleSource(OutputModelExportState state, DescriptionElementBase element, OutputModelTable factsTable) {
325
        OutputModelTable table = OutputModelTable.FACT_SOURCES;
326
        String[] csvLine = new String[table.getSize()];
327
        Set<DescriptionElementSource> sources = element.getSources();
328
        for (DescriptionElementSource source: sources){
329
            csvLine = new  String[table.getSize()];
330
            Reference ref = source.getCitation();
331
            if ((ref == null) && (source.getNameUsedInSource() == null)){
332
                continue;
333
            }
334
            if (ref != null){
335
                if (state.getReferenceFromStore(ref.getId()) == null){
336
                    handleReference(state, ref);
337
                    csvLine[table.getIndex(OutputModelTable.REFERENCE_FK)] = getId(state, ref);
338
                }
339
            }
340
            csvLine[table.getIndex(OutputModelTable.FACT_FK)] = getId(state, element);
341

    
342
            csvLine[table.getIndex(OutputModelTable.NAME_IN_SOURCE_FK)] = getId(state, source.getNameUsedInSource());
343
            csvLine[table.getIndex(OutputModelTable.FACT_TYPE)] = factsTable.getTableName();
344
            if ( StringUtils.isBlank(csvLine[table.getIndex(OutputModelTable.REFERENCE_FK)])  && StringUtils.isBlank(csvLine[table.getIndex(OutputModelTable.NAME_IN_SOURCE_FK)])){
345
                continue;
346
            }
347
            state.getProcessor().put(table, source, csvLine, state);
348
        }
349

    
350
    }
351

    
352
    /**
353
     * @param state
354
     * @param distributionFacts
355
     */
356
    private void handleDistributionFacts(OutputModelExportState state, Taxon taxon, List<DescriptionElementBase> distributionFacts) {
357
        OutputModelTable table = OutputModelTable.GEOGRAPHIC_AREA_FACT;
358
        String[] csvLine = new String[table.getSize()];
359

    
360
        for (DescriptionElementBase element: distributionFacts){
361
            if (element instanceof Distribution){
362
                Distribution distribution = (Distribution)element;
363
                csvLine[table.getIndex(OutputModelTable.FACT_ID)] = getId(state, element);
364
                handleSource(state, element, table);
365
                csvLine[table.getIndex(OutputModelTable.TAXON_FK)] = getId(state, taxon);
366
                if (distribution.getArea() != null){ csvLine[table.getIndex(OutputModelTable.AREA_LABEL)] = distribution.getArea().getLabel();}
367
                if (distribution.getStatus() != null){ csvLine[table.getIndex(OutputModelTable.STATUS_LABEL)] = distribution.getStatus().getLabel();}
368
                state.getProcessor().put(table, distribution, csvLine, state);
369
            } else{
370
                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());
371
            }
372
        }
373
    }
374

    
375
    /**
376
     * @param state
377
     * @param commonNameFacts
378
     */
379
    private void handleCommonNameFacts(OutputModelExportState state, Taxon taxon, List<DescriptionElementBase> commonNameFacts) {
380
        OutputModelTable table = OutputModelTable.COMMON_NAME_FACT;
381
        String[] csvLine = new String[table.getSize()];
382

    
383
        for (DescriptionElementBase element: commonNameFacts){
384
            if (element instanceof CommonTaxonName){
385
                CommonTaxonName commonName = (CommonTaxonName)element;
386
                csvLine[table.getIndex(OutputModelTable.FACT_ID)] = getId(state, element);
387
                handleSource(state, element, table);
388
                csvLine[table.getIndex(OutputModelTable.TAXON_FK)] = getId(state, taxon);
389
                if (commonName.getName() != null){csvLine[table.getIndex(OutputModelTable.FACT_TEXT)] = commonName.getName();}
390
                if (commonName.getLanguage() != null){csvLine[table.getIndex(OutputModelTable.LANGUAGE)] = commonName.getLanguage().getLabel();}
391
                if (commonName.getArea() != null){ csvLine[table.getIndex(OutputModelTable.AREA_LABEL)] = commonName.getArea().getLabel();}
392
                state.getProcessor().put(table, commonName, csvLine, state);
393
            } else{
394
                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());
395
            }
396
        }
397

    
398
    }
399

    
400
    /**
401
     * @param sec
402
     * @return
403
     */
404
    private String getTitleCache(IIdentifiableEntity identEntity) {
405
        if (identEntity == null){
406
            return "";
407
        }
408
        //TODO refresh?
409
        return identEntity.getTitleCache();
410
    }
411

    
412
    /**
413
     * @param state
414
     * @param taxon
415
     * @return
416
     */
417
    private String getId(OutputModelExportState state, ICdmBase cdmBase) {
418
        if (cdmBase == null){
419
            return "";
420
        }
421
        //TODO make configurable
422
        return cdmBase.getUuid().toString();
423
    }
424

    
425
    /**
426
     * @param state
427
     * @param syn
428
     */
429
    private void handleSynonym(OutputModelExportState state, Synonym syn) {
430
       TaxonName name = syn.getName();
431
       handleName(state, name);
432

    
433
       OutputModelTable table = OutputModelTable.SYNONYM;
434
       String[] csvLine = new String[table.getSize()];
435

    
436
       csvLine[table.getIndex(OutputModelTable.SYNONYM_ID)] = getId(state, syn);
437
       csvLine[table.getIndex(OutputModelTable.TAXON_FK)] = getId(state, syn.getAcceptedTaxon());
438
       csvLine[table.getIndex(OutputModelTable.NAME_FK)] = getId(state, name);
439
       csvLine[table.getIndex(OutputModelTable.SEC_REFERENCE_FK)] = getId(state, syn.getSec());
440
       csvLine[table.getIndex(OutputModelTable.SEC_REFERENCE)] = getTitleCache(syn.getSec());
441

    
442
       state.getProcessor().put(table, syn, csvLine, state);
443
    }
444

    
445
    /**
446
     * @param state
447
     * @param name
448
     */
449
    private void handleName(OutputModelExportState state, TaxonName name) {
450
        Rank rank = name.getRank();
451
        OutputModelTable table = OutputModelTable.SCIENTIFIC_NAME;
452
        name = HibernateProxyHelper.deproxy(name);
453
        String[] csvLine = new String[table.getSize()];
454

    
455
        csvLine[table.getIndex(OutputModelTable.NAME_ID)] = getId(state, name);
456
        if (name.getLsid() != null){
457
            csvLine[table.getIndex(OutputModelTable.LSID)] = name.getLsid().getLsid();
458
        }else{
459
            csvLine[table.getIndex(OutputModelTable.LSID)] = "";
460
        }
461

    
462
        handleIdentifier(state, name, csvLine, table);
463
        handleDescriptions(state, name);
464

    
465
        csvLine[table.getIndex(OutputModelTable.RANK)] = getTitleCache(rank);
466
        if (rank != null){
467
            csvLine[table.getIndex(OutputModelTable.RANK_SEQUENCE)] = String.valueOf(rank.getOrderIndex());
468
            if (rank.isInfraGeneric()){
469
                try {
470
                    csvLine[table.getIndex(OutputModelTable.INFRAGENERIC_RANK)] = name.getRank().getInfraGenericMarker();
471
                } catch (UnknownCdmTypeException e) {
472
                    // TODO Auto-generated catch block
473
                    e.printStackTrace();
474
                }
475
            }
476
            if (rank.isInfraSpecific()){
477
                csvLine[table.getIndex(OutputModelTable.INFRASPECIFIC_RANK)] = name.getRank().getAbbreviation();
478
            }
479
        }else{
480
            csvLine[table.getIndex(OutputModelTable.RANK_SEQUENCE)] = "";
481
        }
482
        if (name.isProtectedTitleCache()){
483
            csvLine[table.getIndex(OutputModelTable.FULL_NAME_WITH_AUTHORS)] =name.getTitleCache();
484
        }else{
485
            csvLine[table.getIndex(OutputModelTable.FULL_NAME_WITH_AUTHORS)] = getTropicosTitleCache(name);
486
        }
487
        csvLine[table.getIndex(OutputModelTable.FULL_NAME_NO_AUTHORS)] = name.getNameCache();
488
        csvLine[table.getIndex(OutputModelTable.GENUS_UNINOMIAL)] = name.getGenusOrUninomial();
489

    
490
        csvLine[table.getIndex(OutputModelTable.INFRAGENERIC_EPITHET)] = name.getInfraGenericEpithet();
491
        csvLine[table.getIndex(OutputModelTable.SPECIFIC_EPITHET)] = name.getSpecificEpithet();
492

    
493
        csvLine[table.getIndex(OutputModelTable.INFRASPECIFIC_EPITHET)] = name.getInfraSpecificEpithet();
494
        csvLine[table.getIndex(OutputModelTable.BAS_AUTHORTEAM_FK)] = getId(state,name.getBasionymAuthorship());
495
        if (name.getBasionymAuthorship() != null){
496
            if (state.getAuthorFromStore(name.getBasionymAuthorship().getId()) == null) {
497
                handleAuthor(state, name.getBasionymAuthorship());
498
            }
499
        }
500
        csvLine[table.getIndex(OutputModelTable.BAS_EX_AUTHORTEAM_FK)] = getId(state, name.getExBasionymAuthorship());
501
        if (name.getExBasionymAuthorship() != null){
502
            if (state.getAuthorFromStore(name.getExBasionymAuthorship().getId()) == null) {
503
                handleAuthor(state, name.getExBasionymAuthorship());
504
            }
505

    
506
        }
507
        csvLine[table.getIndex(OutputModelTable.COMB_AUTHORTEAM_FK)] = getId(state,name.getCombinationAuthorship());
508
        if (name.getCombinationAuthorship() != null){
509
            if (state.getAuthorFromStore(name.getCombinationAuthorship().getId()) == null) {
510
                handleAuthor(state, name.getCombinationAuthorship());
511
            }
512
        }
513
        csvLine[table.getIndex(OutputModelTable.COMB_EX_AUTHORTEAM_FK)] = getId(state, name.getExCombinationAuthorship());
514
        if (name.getExCombinationAuthorship() != null){
515
            if (state.getAuthorFromStore(name.getExCombinationAuthorship().getId()) == null) {
516
                handleAuthor(state, name.getExCombinationAuthorship());
517
            }
518

    
519
        }
520

    
521
        csvLine[table.getIndex(OutputModelTable.AUTHOR_TEAM_STRING)] = name.getAuthorshipCache();
522

    
523
        Reference nomRef = (Reference)name.getNomenclaturalReference();
524

    
525
        if (nomRef != null){
526
            if (state.getReferenceFromStore(nomRef.getId()) == null){
527
                handleReference(state, nomRef);
528
            }
529
            csvLine[table.getIndex(OutputModelTable.REFERENCE_FK)] = getId(state, nomRef);
530
            csvLine[table.getIndex(OutputModelTable.PUBLICATION_TYPE)] = nomRef.getType().name();
531
            if (nomRef.getVolume() != null){
532
                csvLine[table.getIndex(OutputModelTable.VOLUME_ISSUE)] = nomRef.getVolume();
533
            }
534
            if (nomRef.getDatePublished() != null){
535
                csvLine[table.getIndex(OutputModelTable.DATE_PUBLISHED)] = nomRef.getDatePublishedString();
536
                csvLine[table.getIndex(OutputModelTable.YEAR_PUBLISHED)] = nomRef.getDatePublished().getYear();
537
            }
538
            if (name.getNomenclaturalMicroReference() != null){
539
                csvLine[table.getIndex(OutputModelTable.DETAIL)] = name.getNomenclaturalMicroReference();
540
            }
541
            nomRef = HibernateProxyHelper.deproxy(nomRef);
542
            if (nomRef.getInReference() != null){
543
                Reference inReference = nomRef.getInReference();
544
                if (inReference.getInReference() != null){
545
                    inReference = inReference.getInReference();
546
                }
547
                if (inReference.getAbbrevTitle() == null){
548
                    csvLine[table.getIndex(OutputModelTable.ABBREV_TITLE)] = CdmUtils.Nz(inReference.getAbbrevTitleCache());
549
                }else{
550
                    csvLine[table.getIndex(OutputModelTable.ABBREV_TITLE)] = CdmUtils.Nz(inReference.getAbbrevTitle());
551
                }
552
                if (inReference.getTitle() == null){
553
                    csvLine[table.getIndex(OutputModelTable.FULL_TITLE)] = CdmUtils.Nz(inReference.getTitleCache());
554
                }else{
555
                    csvLine[table.getIndex(OutputModelTable.FULL_TITLE)] = CdmUtils.Nz(inReference.getTitle());
556
                }
557

    
558

    
559
                TeamOrPersonBase author = inReference.getAuthorship();
560
                if (author != null && (nomRef.isOfType(ReferenceType.BookSection) || nomRef.isOfType(ReferenceType.Section))){
561
                    csvLine[table.getIndex(OutputModelTable.ABBREV_REF_AUTHOR)] = CdmUtils.Nz(author.getNomenclaturalTitle());
562
                    csvLine[table.getIndex(OutputModelTable.FULL_REF_AUTHOR)] = CdmUtils.Nz(author.getTitleCache());
563
                }else{
564
                    csvLine[table.getIndex(OutputModelTable.ABBREV_REF_AUTHOR)] = "";
565
                    csvLine[table.getIndex(OutputModelTable.FULL_REF_AUTHOR)] = "";
566
                }
567
            }else{
568
                csvLine[table.getIndex(OutputModelTable.ABBREV_TITLE)] = "";
569
                csvLine[table.getIndex(OutputModelTable.FULL_TITLE)] = "";
570
                csvLine[table.getIndex(OutputModelTable.ABBREV_REF_AUTHOR)]= "";
571
                csvLine[table.getIndex(OutputModelTable.FULL_REF_AUTHOR)] = "";
572

    
573
            }
574
        }else{
575
            csvLine[table.getIndex(OutputModelTable.PUBLICATION_TYPE)] = "";
576
        }
577

    
578

    
579

    
580
       /*
581
        * Collation
582

    
583
        Detail
584

    
585

    
586
        TitlePageYear
587
        */
588
        Set<TaxonNameDescription> descriptions = name.getDescriptions();
589
        String protologueUriString = extractURIs(descriptions, Feature.PROTOLOGUE());
590

    
591
        csvLine[table.getIndex(OutputModelTable.PROTOLOGUE_URI)] = protologueUriString;
592

    
593
        if (name.getStatus() == null || name.getStatus().isEmpty()){
594
            csvLine[table.getIndex(OutputModelTable.NOM_STATUS)] = "";
595
            csvLine[table.getIndex(OutputModelTable.NOM_STATUS_ABBREV)] = "";
596
        }else{
597

    
598
            String statusStringAbbrev = extractStatusString(name, true);
599
            String statusString = extractStatusString(name, false);
600

    
601
            csvLine[table.getIndex(OutputModelTable.NOM_STATUS)] = statusString.trim();
602
            csvLine[table.getIndex(OutputModelTable.NOM_STATUS_ABBREV)] = statusStringAbbrev.trim();
603
        }
604

    
605
        HomotypicalGroup group =name.getHomotypicalGroup();
606

    
607
        if (state.getHomotypicalGroupFromStore(group.getId()) == null){
608
            handleHomotypicalGroup(state, group);
609
        }
610
        csvLine[table.getIndex(OutputModelTable.HOMOTYPIC_GROUP_FK)] = getId(state, group);
611
        List<TaxonName> typifiedNames = new ArrayList<>();
612
        typifiedNames.addAll(group.getTypifiedNames());
613
        Collections.sort(typifiedNames, new HomotypicalGroupNameComparator(null, true));
614
        Integer  seqNumber= typifiedNames.indexOf(name);
615
        csvLine[table.getIndex(OutputModelTable.HOMOTYPIC_GROUP_SEQ)] = String.valueOf(seqNumber);
616
        state.getProcessor().put(table, name, csvLine, state);
617

    
618
/*
619
 *
620
Tropicos_ID
621
IPNI_ID
622

    
623

    
624
InfragenericRank
625

    
626

    
627
InfraspecificRank
628
Collation
629
Volume (Issue)
630
Detail
631
DatePublished
632
YearPublished
633
TitlePageYear
634

    
635

    
636

    
637
HomotypicGroupSequenceNumber
638

    
639

    
640
 *
641
 */
642
    }
643

    
644
    /**
645
     * @param state
646
     * @param name
647
     */
648
    private void handleIdentifier(OutputModelExportState state, TaxonName name, String[] csvLine, OutputModelTable table) {
649
        Set<String>  IPNIidentifiers = name.getIdentifiers(DefinedTerm.IPNI_NAME_IDENTIFIER());
650
        Set<String>  tropicosIdentifiers = name.getIdentifiers(DefinedTerm.TROPICOS_NAME_IDENTIFIER());
651
        Set<String>  WFOIdentifiers = name.getIdentifiers(DefinedTerm.uuidWfoNameIdentifier);
652
        if (!IPNIidentifiers.isEmpty()){ extractIdentifier(IPNIidentifiers, csvLine, table.getIndex(OutputModelTable.IPNI_ID));}
653
        if (!tropicosIdentifiers.isEmpty()){extractIdentifier(tropicosIdentifiers, csvLine, table.getIndex(OutputModelTable.TROPICOS_ID));}
654
        if (!WFOIdentifiers.isEmpty()){extractIdentifier(WFOIdentifiers,  csvLine, table.getIndex(OutputModelTable.WFO_ID));}
655
    }
656

    
657
    /**
658
     * @param tropicosIdentifiers
659
     */
660
    private void extractIdentifier(Set<String> identifierSet, String[] csvLine, int index) {
661
        String identifierString = "";
662
        for (String identifier: identifierSet){
663
            if (!StringUtils.isBlank(identifierString)){
664
                identifierString += ", ";
665
            }
666
            identifierString += identifier;
667
        }
668

    
669
        csvLine[index] = identifierString;
670
    }
671

    
672
    /**
673
     * @param descriptions
674
     * @return
675
     */
676
    private String extractURIs(Set<?> descriptions, Feature feature) {
677
        String mediaUriString = "";
678
        boolean first = true;
679
        SpecimenDescription specimenDescription;
680
        TaxonDescription taxonDescription;
681
        TaxonNameDescription nameDescription;
682
        Set<DescriptionElementBase> elements = new HashSet();
683
        Set<DescriptionBase> descriptionsSet = (Set<DescriptionBase>)descriptions;
684
        for (DescriptionBase description : descriptionsSet){
685
            if (!description.getElements().isEmpty()){
686
                if (description instanceof SpecimenDescription){
687
                    specimenDescription = (SpecimenDescription)description;
688
                    elements = specimenDescription.getElements();
689
                }else if (description instanceof TaxonDescription){
690
                    taxonDescription = (TaxonDescription) description;
691
                    elements = taxonDescription.getElements();
692
                } else if (description instanceof TaxonNameDescription){
693
                    nameDescription = (TaxonNameDescription) description;
694
                    elements = nameDescription.getElements();
695
                }
696

    
697
                for (DescriptionElementBase element : elements){
698
                    Feature entityFeature = HibernateProxyHelper.deproxy(element.getFeature());
699
                    if (entityFeature.equals(feature)){
700
                        if (!element.getMedia().isEmpty()){
701
                            List<Media> media = element.getMedia();
702
                            for (Media mediaElement: media){
703
                                Iterator<MediaRepresentation> it =  mediaElement.getRepresentations().iterator();
704
                                mediaUriString = extractMediaUris(it);
705
                            }
706
                        }
707
                    }
708
                }
709
            }
710
        }
711
        return mediaUriString;
712
    }
713

    
714
    /**
715
     * @param state
716
     * @param basionymAuthorship
717
     */
718
    private void handleAuthor(OutputModelExportState state, TeamOrPersonBase author) {
719
        if (state.getAuthorFromStore(author.getId()) != null){
720
            return;
721
        }
722
        state.addAuthorToStore(author);
723
        OutputModelTable table = OutputModelTable.NOMENCLATURAL_AUTHOR;
724
        String[] csvLine = new String[table.getSize()];
725
        OutputModelTable tableAuthorRel = OutputModelTable.NOMENCLATURAL_AUTHOR_TEAM_RELATION;
726
        String[] csvLineRel = new String[tableAuthorRel.getSize()];
727
        String[] csvLineMember = new String[table.getSize()];
728
        csvLine[table.getIndex(OutputModelTable.AUTHOR_ID)] = getId(state, author);
729
        csvLine[table.getIndex(OutputModelTable.ABBREV_AUTHOR)] = author.getNomenclaturalTitle();
730
        csvLine[table.getIndex(OutputModelTable.AUTHOR_TITLE)] = author.getTitleCache();
731
        author = HibernateProxyHelper.deproxy(author);
732
        if (author instanceof Person){
733
            Person authorPerson = (Person)author;
734
            csvLine[table.getIndex(OutputModelTable.AUTHOR_FIRST_NAME)] = authorPerson.getFirstname();
735
            csvLine[table.getIndex(OutputModelTable.AUTHOR_LASTNAME)] = authorPerson.getLastname();
736
            csvLine[table.getIndex(OutputModelTable.AUTHOR_PREFIX)] = authorPerson.getPrefix();
737
            csvLine[table.getIndex(OutputModelTable.AUTHOR_SUFFIX)] = authorPerson.getSuffix();
738
        } else{
739
            // create an entry in rel table and all members in author table, check whether the team members already in author table
740

    
741
            Team authorTeam = (Team)author;
742
            int index = 0;
743
            for (Person member: authorTeam.getTeamMembers()){
744
                csvLineRel = new String[tableAuthorRel.getSize()];
745
                csvLineRel[tableAuthorRel.getIndex(OutputModelTable.AUTHOR_TEAM_FK)] = getId(state, authorTeam);
746
                csvLineRel[tableAuthorRel.getIndex(OutputModelTable.AUTHOR_FK)] = getId(state, member);
747
                csvLineRel[tableAuthorRel.getIndex(OutputModelTable.AUTHOR_TEAM_SEQ_NUMBER)] = String.valueOf(index);
748
                state.getProcessor().put(tableAuthorRel, authorTeam.getId() +":" +member.getId(), csvLineRel, state);
749

    
750
                if (state.getAuthorFromStore(member.getId()) == null){
751
                    state.addAuthorToStore(member);
752
                    csvLineMember = new String[table.getSize()];
753
                    csvLineMember[table.getIndex(OutputModelTable.AUTHOR_ID)] = getId(state, member);
754
                    csvLineMember[table.getIndex(OutputModelTable.ABBREV_AUTHOR)] = member.getNomenclaturalTitle();
755
                    csvLineMember[table.getIndex(OutputModelTable.AUTHOR_TITLE)] = member.getTitleCache();
756
                    csvLineMember[table.getIndex(OutputModelTable.AUTHOR_FIRST_NAME)] = member.getFirstname();
757
                    csvLineMember[table.getIndex(OutputModelTable.AUTHOR_LASTNAME)] = member.getLastname();
758
                    csvLineMember[table.getIndex(OutputModelTable.AUTHOR_PREFIX)] = member.getPrefix();
759
                    csvLineMember[table.getIndex(OutputModelTable.AUTHOR_SUFFIX)] = member.getSuffix();
760
                    state.getProcessor().put(table, member, csvLineMember, state);
761
                }
762
                index++;
763

    
764
            }
765
        }
766
        state.getProcessor().put(table, author, csvLine, state);
767

    
768

    
769

    
770

    
771
    }
772

    
773
    /**
774
     * @param name
775
     * @param statusString
776
     * @return
777
     */
778
    private String extractStatusString(TaxonName name, boolean abbrev) {
779
        Set<NomenclaturalStatus> status = name.getStatus();
780
        if (status.isEmpty()){
781
            return "";
782
        }
783
        String statusString = "";
784
        for (NomenclaturalStatus nameStatus: status){
785
            if (nameStatus != null){
786
                if (abbrev){
787
                    if (nameStatus.getType() != null){
788
                        statusString += nameStatus.getType().getIdInVocabulary();
789
                    }
790
                }else{
791
                    if (nameStatus.getType() != null){
792
                        statusString += nameStatus.getType().getTitleCache();
793
                    }
794
                }
795
                if (!abbrev){
796

    
797
                    if (nameStatus.getRuleConsidered() != null && !StringUtils.isBlank(nameStatus.getRuleConsidered())){
798
                        statusString += " " + nameStatus.getRuleConsidered();
799
                    }
800
                    if (nameStatus.getCitation() != null){
801
                        statusString += " " + nameStatus.getCitation().getTitleCache();
802
                    }
803
                    if (nameStatus.getCitationMicroReference() != null && !StringUtils.isBlank(nameStatus.getCitationMicroReference())){
804
                        statusString += " " + nameStatus.getCitationMicroReference();
805
                    }
806
                }
807
                statusString += " ";
808
            }
809
        }
810
        return statusString;
811
    }
812

    
813
    /**
814
     * @param group
815
     */
816
    private void handleHomotypicalGroup(OutputModelExportState state, HomotypicalGroup group) {
817
        state.addHomotypicalGroupToStore(group);
818
        OutputModelTable table = OutputModelTable.HOMOTYPIC_GROUP;
819
        String[] csvLine = new String[table.getSize()];
820

    
821
        csvLine[table.getIndex(OutputModelTable.HOMOTYPIC_GROUP_ID)] = getId(state, group);
822
        List<TaxonName> typifiedNames = new ArrayList<>();
823
        typifiedNames.addAll(group.getTypifiedNames());
824
        Collections.sort(typifiedNames, new HomotypicalGroupNameComparator(null, true));
825
        String typifiedNamesString = "";
826
        for (TaxonName name: typifiedNames){
827
            //Concatenated output string for homotypic group (names and citations) + status + some name relations (e.g. “non”)
828
//TODO: nameRelations, which and how to display
829

    
830

    
831
            typifiedNamesString += name.getTitleCache()+ extractStatusString(name, true) + "; ";
832
        }
833
        typifiedNamesString = typifiedNamesString.substring(0, typifiedNamesString.length()-2);
834
        if (typifiedNamesString != null){
835
            csvLine[table.getIndex(OutputModelTable.HOMOTYPIC_GROUP_STRING)] = typifiedNamesString.trim();
836
        }else{
837
            csvLine[table.getIndex(OutputModelTable.HOMOTYPIC_GROUP_STRING)] = "";
838
        }
839
        Set<TypeDesignationBase> typeDesigantions = group.getTypeDesignations();
840
        List<TypeDesignationBase> designationList = new ArrayList<>();
841
        designationList.addAll(typeDesigantions);
842
        Collections.sort(designationList, new TypeComparator());
843
        StringBuffer typeDesignationString = new StringBuffer();
844
        for (TypeDesignationBase typeDesignation: typeDesigantions){
845
            if (typeDesignation != null && typeDesignation.getTypeStatus() != null){
846
                typeDesignationString.append(typeDesignation.getTypeStatus().getTitleCache() + ": ");
847
            }
848
            if (typeDesignation instanceof SpecimenTypeDesignation){
849
                if (((SpecimenTypeDesignation)typeDesignation).getTypeSpecimen() != null){
850
                    typeDesignationString.append(((SpecimenTypeDesignation)typeDesignation).getTypeSpecimen().getTitleCache());
851
                    handleSpecimen(state, ((SpecimenTypeDesignation)typeDesignation).getTypeSpecimen());
852
                }
853
            }else{
854
                if (((NameTypeDesignation)typeDesignation).getTypeName() != null){
855
                    typeDesignationString.append(((NameTypeDesignation)typeDesignation).getTypeName().getTitleCache());
856
                }
857
            }
858
            if(typeDesignation.getCitation() != null ){
859
                typeDesignationString.append(", "+typeDesignation.getCitation().getTitleCache());
860
            }
861
            //TODO...
862
            /*
863
             * Sortierung:
864
            1.  Status der Typen: a) holo, lecto, neo, syn, b) epi, paralecto, c) para (wenn überhaupt) – die jeweiligen iso immer direct mit dazu
865
            2.  Land
866
            3.  Sammler
867
            4.  Nummer
868

    
869
            Aufbau der Typusinformationen:
870
            Land: Lokalität mit Höhe und Koordinaten; Datum; Sammler Nummer (Herbar/Barcode, Typusart; Herbar/Barcode, Typusart …)
871

    
872
             */
873
        }
874
        String typeDesignations = typeDesignationString.toString();
875
        if (typeDesignations != null){
876
            csvLine[table.getIndex(OutputModelTable.TYPE_STRING)] = typeDesignations;
877
        }else{
878
            csvLine[table.getIndex(OutputModelTable.TYPE_STRING)] = "";
879
        }
880
        state.getProcessor().put(table, String.valueOf(group.getId()), csvLine, state);
881

    
882
    }
883

    
884
    /**
885
     * @param name
886
     * @return
887
     */
888
    private String getTropicosTitleCache(TaxonName name) {
889
        String basionymStart = "(";
890
        String basionymEnd = ") ";
891
        String exAuthorSeperator = " ex ";
892
        TeamOrPersonBase combinationAuthor = name.getCombinationAuthorship();
893
        TeamOrPersonBase exCombinationAuthor = name.getExCombinationAuthorship();
894
        TeamOrPersonBase basionymAuthor = name.getBasionymAuthorship();
895
        TeamOrPersonBase exBasionymAuthor = name.getExBasionymAuthorship();
896

    
897
        String combinationAuthorString = "";
898
        if (combinationAuthor != null){
899
            combinationAuthor = HibernateProxyHelper.deproxy(combinationAuthor);
900
            if (combinationAuthor instanceof Team){
901
                combinationAuthorString = createTropicosTeamTitle(combinationAuthor);
902
            }else{
903
                Person person = HibernateProxyHelper.deproxy(combinationAuthor, Person.class);
904
                combinationAuthorString = createTropicosAuthorString(person);
905
            }
906
        }
907
        String exCombinationAuthorString = "";
908
        if (exCombinationAuthor != null){
909
            exCombinationAuthor = HibernateProxyHelper.deproxy(exCombinationAuthor);
910
            if (exCombinationAuthor instanceof Team){
911
               exCombinationAuthorString = createTropicosTeamTitle(exCombinationAuthor);
912
            }else{
913
                Person person = HibernateProxyHelper.deproxy(exCombinationAuthor, Person.class);
914
                exCombinationAuthorString = createTropicosAuthorString(person);
915
            }
916
        }
917

    
918
        String basionymAuthorString = "";
919
        if (basionymAuthor != null){
920
            basionymAuthor = HibernateProxyHelper.deproxy(basionymAuthor);
921
            if (basionymAuthor instanceof Team){
922
                basionymAuthorString =  createTropicosTeamTitle(basionymAuthor);
923
            }else{
924
                Person person = HibernateProxyHelper.deproxy(basionymAuthor, Person.class);
925
                basionymAuthorString = createTropicosAuthorString(person);
926
            }
927
        }
928

    
929
        String exBasionymAuthorString = "";
930

    
931
        if (exBasionymAuthor != null){
932
;            exBasionymAuthor = HibernateProxyHelper.deproxy(exBasionymAuthor);
933
            if (exBasionymAuthor instanceof Team){
934
                exBasionymAuthorString = createTropicosTeamTitle(exBasionymAuthor);
935

    
936
            }else{
937
                Person person = HibernateProxyHelper.deproxy(exBasionymAuthor, Person.class);
938
                exBasionymAuthorString = createTropicosAuthorString(person);
939
            }
940
        }
941
        String completeAuthorString =  name.getNameCache() + " ";
942

    
943
        completeAuthorString += (!CdmUtils.isBlank(exBasionymAuthorString) || !CdmUtils.isBlank(basionymAuthorString)) ? basionymStart: "";
944
        completeAuthorString += (!CdmUtils.isBlank(exBasionymAuthorString)) ? (CdmUtils.Nz(exBasionymAuthorString) + exAuthorSeperator): "" ;
945
        completeAuthorString += (!CdmUtils.isBlank(basionymAuthorString))? CdmUtils.Nz(basionymAuthorString):"";
946
        completeAuthorString += (!CdmUtils.isBlank(exBasionymAuthorString) || !CdmUtils.isBlank(basionymAuthorString)) ?  basionymEnd:"";
947
        completeAuthorString += (!CdmUtils.isBlank(exCombinationAuthorString)) ? (CdmUtils.Nz(exCombinationAuthorString) + exAuthorSeperator): "" ;
948
        completeAuthorString += (!CdmUtils.isBlank(combinationAuthorString))? CdmUtils.Nz(combinationAuthorString):"";
949

    
950

    
951
        return completeAuthorString;
952
    }
953

    
954
    /**
955
     * @param combinationAuthor
956
     * @return
957
     */
958
    private String createTropicosTeamTitle(TeamOrPersonBase combinationAuthor) {
959
        String combinationAuthorString;
960
        Team team = HibernateProxyHelper.deproxy(combinationAuthor, Team.class);
961
        Team tempTeam = Team.NewInstance();
962
        for (Person teamMember:team.getTeamMembers()){
963
            combinationAuthorString = createTropicosAuthorString(teamMember);
964
            Person tempPerson = Person.NewTitledInstance(combinationAuthorString);
965
            tempTeam.addTeamMember(tempPerson);
966
        }
967
        combinationAuthorString = tempTeam.generateTitle();
968
        return combinationAuthorString;
969
    }
970

    
971
    /**
972
     * @param teamMember
973
     */
974
    private String createTropicosAuthorString(Person teamMember) {
975
        String nomAuthorString = "";
976
        String[] splittedAuthorString = null;
977
        if (teamMember == null){
978
            return nomAuthorString;
979
        }
980

    
981
        if (teamMember.getFirstname() != null){
982
            String firstNameString = teamMember.getFirstname().replaceAll("\\.", "\\. ");
983
            splittedAuthorString = firstNameString.split("\\s");
984
            for (String split: splittedAuthorString){
985
                if (!StringUtils.isBlank(split)){
986
                    nomAuthorString += split.substring(0, 1);
987
                    nomAuthorString += ".";
988
                }
989
            }
990
        }
991
        if (teamMember.getLastname() != null){
992
            String lastNameString = teamMember.getLastname().replaceAll("\\.", "\\. ");
993
            splittedAuthorString = lastNameString.split("\\s");
994
            for (String split: splittedAuthorString){
995
                nomAuthorString += " " +split;
996
            }
997
        }
998
        if (StringUtils.isBlank(nomAuthorString.trim())){
999
            if (teamMember.getTitleCache() != null) {
1000
                String titleCacheString = teamMember.getTitleCache().replaceAll("\\.", "\\. ");
1001
                splittedAuthorString = titleCacheString.split("\\s");
1002
            }
1003

    
1004

    
1005
            int index = 0;
1006
            for (String split: splittedAuthorString){
1007
                if ( index < splittedAuthorString.length-1 && (split.length()==1 || split.endsWith("."))){
1008
                    nomAuthorString += split;
1009
                }else{
1010
                    nomAuthorString = nomAuthorString +" "+ split;
1011
                }
1012
                index++;
1013
            }
1014
        }
1015
        return nomAuthorString.trim();
1016
    }
1017

    
1018
    /**
1019
     * @param state
1020
     * @param name
1021
     */
1022
    private void handleReference(OutputModelExportState state, Reference reference) {
1023
        state.addReferenceToStore(reference);
1024
        OutputModelTable table = OutputModelTable.REFERENCE;
1025

    
1026
        String[] csvLine = new String[table.getSize()];
1027
        csvLine[table.getIndex(OutputModelTable.REFERENCE_ID)] = getId(state, reference);
1028
        //TODO short citations correctly
1029
        String shortCitation = reference.getAbbrevTitleCache();  //Should be Author(year) like in Taxon.sec
1030
        csvLine[table.getIndex(OutputModelTable.BIBLIO_SHORT_CITATION)] = shortCitation;
1031
        //TODO get preferred title
1032
        csvLine[table.getIndex(OutputModelTable.REF_TITLE)] = reference.getTitle();
1033
        csvLine[table.getIndex(OutputModelTable.DATE_PUBLISHED)] = reference.getDatePublishedString();
1034
        //TBC
1035
        csvLine[table.getIndex(OutputModelTable.EDITION)] = reference.getEdition();
1036
        csvLine[table.getIndex(OutputModelTable.EDITOR)] = reference.getEditor();
1037
        csvLine[table.getIndex(OutputModelTable.ISBN)] = reference.getIsbn();
1038
        csvLine[table.getIndex(OutputModelTable.ISSN)] = reference.getIssn();
1039
        csvLine[table.getIndex(OutputModelTable.ORGANISATION)] = reference.getOrganization();
1040
        csvLine[table.getIndex(OutputModelTable.PAGES)] = reference.getPages();
1041
        csvLine[table.getIndex(OutputModelTable.PLACE_PUBLISHED)] = reference.getPlacePublished();
1042
        csvLine[table.getIndex(OutputModelTable.PUBLISHER)] = reference.getPublisher();
1043
        csvLine[table.getIndex(OutputModelTable.REF_ABSTRACT)] = reference.getReferenceAbstract();
1044
        csvLine[table.getIndex(OutputModelTable.SERIES_PART)] = reference.getSeriesPart();
1045
        csvLine[table.getIndex(OutputModelTable.VOLUME)] = reference.getVolume();
1046
        csvLine[table.getIndex(OutputModelTable.YEAR)] = reference.getYear();
1047
        if ( reference.getAuthorship() != null){
1048
            csvLine[table.getIndex(OutputModelTable.AUTHORSHIP_TITLE)] = reference.getAuthorship().getTitleCache();
1049
            csvLine[table.getIndex(OutputModelTable.AUTHOR_FK)] = getId(state,reference.getAuthorship());
1050
        }
1051

    
1052
        csvLine[table.getIndex(OutputModelTable.IN_REFERENCE)] = getId(state, reference.getInReference());
1053
        if (reference.getInReference() != null && state.getReferenceFromStore(reference.getInReference().getId()) == null){
1054
            handleReference(state, reference.getInReference());
1055
        }
1056
        if ( reference.getInstitution() != null){ csvLine[table.getIndex(OutputModelTable.INSTITUTION)] = reference.getInstitution().getTitleCache();}
1057
        if ( reference.getLsid() != null){ csvLine[table.getIndex(OutputModelTable.LSID)] = reference.getLsid().getLsid();}
1058
        if ( reference.getSchool() != null){ csvLine[table.getIndex(OutputModelTable.SCHOOL)] = reference.getSchool().getTitleCache();}
1059
        if ( reference.getUri() != null){ csvLine[table.getIndex(OutputModelTable.URI)] = reference.getUri().toString();}
1060
        csvLine[table.getIndex(OutputModelTable.REF_TYPE)] = reference.getType().getKey();
1061

    
1062
        state.getProcessor().put(table, reference, csvLine, state);
1063

    
1064
    }
1065

    
1066

    
1067
    /*
1068
     * TypeDesignation table
1069
     * Specimen_Fk
1070
     *  EditName_Fk
1071
     *   TypeVerbatimCitation
1072
     *   TypeCategory
1073
     *   TypeDesignatedByString
1074
     *   TypeDesignatedByRef_Fk
1075
     */
1076

    
1077
    private void handleSpecimenTypeDesignations(OutputModelExportState state, TaxonName name){
1078
       Set<SpecimenTypeDesignation> typeDesignations = name.getSpecimenTypeDesignations();
1079
       OutputModelTable table = OutputModelTable.TYPE_DESIGNATION;
1080
       String nameId = getId(state, name);
1081
       String[] csvLine = new String[table.getSize()];
1082
        for (SpecimenTypeDesignation specimenType: typeDesignations){
1083
            DerivedUnit specimen = specimenType.getTypeSpecimen();
1084
            if (state.getSpecimenFromStore(specimen.getId()) == null){
1085
                handleSpecimen(state, specimen);
1086
            }
1087
            csvLine[table.getIndex(OutputModelTable.SPECIMEN_FK)] = getId(state, specimenType.getTypeSpecimen());
1088
            csvLine[table.getIndex(OutputModelTable.NAME_FK)] = nameId;
1089
            csvLine[table.getIndex(OutputModelTable.TYPE_VERBATIM_CITATION)] = specimenType.getTypeSpecimen().generateTitle();
1090
            //TODO: add link to existing Vorcabulary
1091
            csvLine[table.getIndex(OutputModelTable.TYPE_CATEGORY)] = "";
1092
            csvLine[table.getIndex(OutputModelTable.TYPE_DESIGNATED_BY_STRING)] = specimenType.getCitation().getTitleCache();
1093
            csvLine[table.getIndex(OutputModelTable.TYPE_DESIGNATED_BY_REF_FK)] = getId(state, specimenType.getCitation());
1094
        }
1095
    }
1096

    
1097
    /**
1098
     * @param state
1099
     * @param specimen
1100
     */
1101
    private void handleSpecimen(OutputModelExportState state, DerivedUnit specimen) {
1102
        state.addSpecimenToStore(specimen);
1103
        OutputModelTable table = OutputModelTable.SPECIMEN;
1104
        String specimenId = getId(state, specimen);
1105
        String[] csvLine = new String[table.getSize()];
1106

    
1107
        csvLine[table.getIndex(OutputModelTable.SPECIMEN_ID)] = specimenId;
1108
        csvLine[table.getIndex(OutputModelTable.SPECIMEN_CITATION)] = specimen.getTitleCache();
1109
        csvLine[table.getIndex(OutputModelTable.SPECIMEN_IMAGE_URIS)] = extractURIs(specimen.getDescriptions(), Feature.IMAGE());
1110
        if (specimen.getCollection() != null){ csvLine[table.getIndex(OutputModelTable.HERBARIUM_ABBREV)] = specimen.getCollection().getCode();}
1111
        if (specimen instanceof MediaSpecimen){
1112
            MediaSpecimen mediaSpecimen = (MediaSpecimen) specimen;
1113
            Iterator<MediaRepresentation> it = mediaSpecimen.getMediaSpecimen().getRepresentations().iterator();
1114
            String mediaUris = extractMediaUris(it);
1115
            csvLine[table.getIndex(OutputModelTable.MEDIA_SPECIMEN_URL)] = mediaUris;
1116

    
1117
        }
1118

    
1119
        if (specimen.getDerivedFrom() != null){
1120
            for (SpecimenOrObservationBase original: specimen.getDerivedFrom().getOriginals()){
1121
                //TODO: What to do if there are more then one FieldUnit??
1122
                if (original instanceof FieldUnit){
1123
                    FieldUnit fieldUnit = (FieldUnit)original;
1124
                    csvLine[table.getIndex(OutputModelTable.COLLECTOR_NUMBER)] = fieldUnit.getFieldNumber();
1125

    
1126
                    GatheringEvent gathering = fieldUnit.getGatheringEvent();
1127
                    if (gathering != null){
1128
                        if (gathering.getLocality() != null){ csvLine[table.getIndex(OutputModelTable.LOCALITY)] = gathering.getLocality().getLanguageLabel();}
1129
                        if (gathering.getCountry() != null){csvLine[table.getIndex(OutputModelTable.COUNTRY)] = gathering.getCountry().getLabel();}
1130
                        csvLine[table.getIndex(OutputModelTable.COLLECTOR_STRING)] = createCollectorString(state, gathering, fieldUnit);
1131
                        addCollectingAreas(gathering);
1132
                        if (gathering.getGatheringDate() != null){csvLine[table.getIndex(OutputModelTable.COLLECTION_DATE)] = gathering.getGatheringDate().toString();}
1133
                        if (!gathering.getCollectingAreas().isEmpty()){
1134
                            int index = 0;
1135
                            csvLine[table.getIndex(OutputModelTable.FURTHER_AREAS)] = "0";
1136
                            for (NamedArea area: gathering.getCollectingAreas()){
1137
                                if (index == 0){
1138
                                    csvLine[table.getIndex(OutputModelTable.AREA_CATEGORY1)] = area.getTermType().getKey();
1139
                                    csvLine[table.getIndex(OutputModelTable.AREA_NAME1)] = area.getLabel();
1140
                                }
1141
                                if (index == 1){
1142
                                    csvLine[table.getIndex(OutputModelTable.AREA_CATEGORY2)] = area.getTermType().getKey();
1143
                                    csvLine[table.getIndex(OutputModelTable.AREA_NAME2)] = area.getLabel();
1144
                                }
1145
                                if (index == 2){
1146
                                    csvLine[table.getIndex(OutputModelTable.AREA_CATEGORY3)] = area.getTermType().getKey();
1147
                                    csvLine[table.getIndex(OutputModelTable.AREA_NAME3)] = area.getLabel();
1148
                                }
1149
                                if (index == 3){
1150
                                    csvLine[table.getIndex(OutputModelTable.FURTHER_AREAS)] = "1";
1151
                                    break;
1152
                                }
1153
                                index++;
1154
                            }
1155
                        }
1156
                    }
1157
                }
1158
            }
1159
        }
1160

    
1161
        state.getProcessor().put(table, specimen, csvLine, state);
1162

    
1163

    
1164

    
1165

    
1166
    }
1167

    
1168
    /**
1169
     * @param it
1170
     */
1171
    private String extractMediaUris(Iterator<MediaRepresentation> it) {
1172
        String mediaUriString = "";
1173
        boolean first = true;
1174
        while(it.hasNext()){
1175
            MediaRepresentation rep = it.next();
1176
            List<MediaRepresentationPart> parts = rep.getParts();
1177
            for (MediaRepresentationPart part: parts){
1178
                if (first){
1179
                    if (part.getUri() != null){
1180
                        mediaUriString += part.getUri().toString();
1181
                        first = false;
1182
                    }
1183
                }else{
1184
                    if (part.getUri() != null){mediaUriString += ", " +part.getUri().toString();}
1185
                }
1186
            }
1187
        }
1188
        return mediaUriString;
1189
    }
1190

    
1191
    /**
1192
     * @param gathering
1193
     */
1194
    private void addCollectingAreas(GatheringEvent gathering) {
1195
        // TODO Auto-generated method stub
1196

    
1197
    }
1198

    
1199
    /**
1200
     * @param gathering
1201
     * @return
1202
     */
1203
    private String createCollectorString(OutputModelExportState state, GatheringEvent gathering, FieldUnit fieldUnit) {
1204
        String collectorString = "";
1205
        if (gathering.getCollector() != null){
1206
           TeamOrPersonBase collector = (TeamOrPersonBase) HibernateProxyHelper.deproxy(gathering.getCollector());
1207
           Person primaryCollector = fieldUnit.getPrimaryCollector();
1208

    
1209
           if (state.getConfig().isHighLightPrimaryCollector()){
1210
               if (collector instanceof Team){
1211
                   Team collectorTeam = (Team)collector;
1212
                   boolean isFirst = true;
1213
                   for (Person member: collectorTeam.getTeamMembers()){
1214
                       if (!isFirst){
1215
                           collectorString += "; ";
1216
                       }
1217
                       if (member.equals(primaryCollector)){
1218
                           //highlight
1219
                           collectorString += "<b>" + member.getTitleCache() + "</b>";
1220
                       }else{
1221
                           collectorString += member.getTitleCache();
1222
                       }
1223
                   }
1224
               }
1225

    
1226
           } else{
1227
               collectorString = collector.getTitleCache();
1228
           }
1229
       }
1230
       return collectorString;
1231
    }
1232

    
1233
    /**
1234
     * {@inheritDoc}
1235
     */
1236
    @Override
1237
    protected boolean doCheck(OutputModelExportState state) {
1238
        return false;
1239
    }
1240

    
1241
    /**
1242
     * {@inheritDoc}
1243
     */
1244
    @Override
1245
    protected boolean isIgnore(OutputModelExportState state) {
1246
        return false;
1247
    }
1248

    
1249

    
1250

    
1251

    
1252

    
1253
}
(1-1/5)