Project

General

Profile

Download (31.7 KB) Statistics
| Branch: | Tag: | Revision:
1
package eu.etaxonomy.cdm.io.csv.caryophyllales.out;
2

    
3
import java.io.ByteArrayOutputStream;
4
import java.io.FileOutputStream;
5
import java.io.OutputStream;
6
import java.io.OutputStreamWriter;
7
import java.io.PrintWriter;
8
import java.util.ArrayList;
9
import java.util.Collections;
10
import java.util.HashMap;
11
import java.util.HashSet;
12
import java.util.Iterator;
13
import java.util.List;
14
import java.util.Set;
15
import java.util.TreeMap;
16
import java.util.UUID;
17

    
18
import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;
19
import org.springframework.beans.factory.annotation.Autowired;
20
import org.springframework.stereotype.Component;
21

    
22
import eu.etaxonomy.cdm.api.service.dto.CondensedDistribution;
23
import eu.etaxonomy.cdm.api.service.pager.Pager;
24
import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;
25
import eu.etaxonomy.cdm.compare.name.HomotypicalGroupComparator;
26
import eu.etaxonomy.cdm.compare.taxon.HomotypicGroupTaxonComparator;
27
import eu.etaxonomy.cdm.ext.geo.CondensedDistributionConfiguration;
28
import eu.etaxonomy.cdm.ext.geo.IEditGeoService;
29
import eu.etaxonomy.cdm.filter.TaxonNodeFilter;
30
import eu.etaxonomy.cdm.io.common.TaxonNodeOutStreamPartitioner;
31
import eu.etaxonomy.cdm.io.common.XmlExportState;
32
import eu.etaxonomy.cdm.model.common.CdmBase;
33
import eu.etaxonomy.cdm.model.common.Language;
34
import eu.etaxonomy.cdm.model.description.DescriptionBase;
35
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
36
import eu.etaxonomy.cdm.model.description.Distribution;
37
import eu.etaxonomy.cdm.model.description.Feature;
38
import eu.etaxonomy.cdm.model.description.TextData;
39
import eu.etaxonomy.cdm.model.location.NamedArea;
40
import eu.etaxonomy.cdm.model.name.HomotypicalGroup;
41
import eu.etaxonomy.cdm.model.name.IBotanicalName;
42
import eu.etaxonomy.cdm.model.name.INonViralName;
43
import eu.etaxonomy.cdm.model.name.NameRelationship;
44
import eu.etaxonomy.cdm.model.name.NameRelationshipType;
45
import eu.etaxonomy.cdm.model.name.NameTypeDesignation;
46
import eu.etaxonomy.cdm.model.name.NameTypeDesignationStatus;
47
import eu.etaxonomy.cdm.model.name.NomenclaturalStatus;
48
import eu.etaxonomy.cdm.model.name.Rank;
49
import eu.etaxonomy.cdm.model.name.TypeDesignationBase;
50
import eu.etaxonomy.cdm.model.reference.Reference;
51
import eu.etaxonomy.cdm.model.taxon.Synonym;
52
import eu.etaxonomy.cdm.model.taxon.Taxon;
53
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
54
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
55
import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
56
import eu.etaxonomy.cdm.persistence.query.MatchMode;
57

    
58

    
59

    
60
/**
61
 * @author k.luther
62
 * @since 2015-Apr
63
 */
64
@Component
65
public class CsvNameExport extends CsvNameExportBase {
66
    private static final long serialVersionUID = 7289805663701807425L;
67

    
68
    private static final Logger logger = LogManager.getLogger(CsvNameExport.class);
69

    
70
    @Autowired
71
    private IEditGeoService geoService;
72

    
73
    private HashMap<UUID, HashMap<String,String>> familyMap = new HashMap<>();
74
    private HashMap<UUID, HashMap<String,String>> genusMap = new HashMap<>();
75

    
76
    private List<HashMap<String,String>> nameRecords = new ArrayList<>();
77

    
78
    public CsvNameExport() {
79
        super();
80
        this.ioName = this.getClass().getSimpleName();
81
    }
82

    
83
    @Override
84
    protected void doInvoke(CsvNameExportState state) {
85
        CsvNameExportConfigurator config = state.getConfig();
86

    
87
        PrintWriter writer = null;
88

    
89
        try {
90

    
91
            switch(config.getTarget()) {
92
            case FILE :
93
                OutputStream os = new FileOutputStream(config.getDestination());
94
                os.write(239);
95
                os.write(187);
96
                os.write(191);
97
                writer = new PrintWriter(new OutputStreamWriter(os, "UTF-8"));
98
                break;
99
            case EXPORT_DATA :
100
                exportStream = new ByteArrayOutputStream();
101
                writer = new PrintWriter(exportStream);
102
                break;
103
            default:
104
                break;
105
            }
106

    
107
            List<HashMap<String, String>> result;
108
            if (config.getRank() == null){
109
                config.setRank(Rank.GENUS());
110
            }
111
            if (config.isNamesOnly()){
112
                txStatus = startTransaction();
113
                result = getNameService().getNameRecords();
114
            } else {
115
                result = getRecordsForPrintPub(state);
116
            }
117
            CsvRecord nameRecord;
118
            int count = 0;
119
            boolean isFirst = true;
120
            for (HashMap<String,String> record:result){
121
                if (count > 0){
122
                    isFirst = false;
123
                }
124
                count++;
125
                nameRecord = new CsvRecord(record, isFirst);
126
                nameRecord.print(writer, config);
127

    
128
            }
129
            if (exportStream != null){
130
                state.getResult().addExportData(getByteArray());
131
                //this.exportData.addExportData(exportStream.toByteArray());
132
            }
133
            writer.flush();
134

    
135
            writer.close();
136

    
137
        } catch (Exception e) {
138
            // TODO Auto-generated catch block
139
            e.printStackTrace();
140
        }
141
        if (txStatus != null  ){
142
            commitTransaction(txStatus);
143
        }
144
        return;
145

    
146

    
147
    }
148

    
149
    @Override
150
    public long countSteps(CsvNameExportState state) {
151
        TaxonNodeFilter filter = state.getConfig().getTaxonNodeFilter();
152
        return getTaxonNodeService().count(filter);
153
    }
154

    
155

    
156
    @Override
157
    protected boolean doCheck(CsvNameExportState state) {
158
        boolean result = true;
159
        logger.warn("No check implemented for " + this.ioName);
160
        return result;
161
    }
162

    
163
    @Override
164
    protected boolean isIgnore(CsvNameExportState state) {
165
        return false;
166
    }
167

    
168

    
169
    public List<HashMap<String,String>> getRecordsForPrintPub(CsvNameExportState state){
170
//        List<String> propertyPaths = new ArrayList<String>();
171
//        propertyPaths.add("childNodes");
172
//        txStatus = startTransaction();
173
//        Classification classification = getClassificationService().load(state.getConfig().getClassificationUUID());
174
//        TaxonNode rootNode;
175
//        if (classification != null){
176
//            rootNode = classification.getRootNode();
177
//        }else{
178
//            List<Classification> classifications = getClassificationService().list(Classification.class, 10, 0, null, null);
179
//            if (classifications.isEmpty()){
180
//                return null;
181
//            }
182
//            classification = classifications.get(0);
183
//            rootNode = classification.getRootNode();
184
//        }
185
//        rootNode = getTaxonNodeService().load(rootNode.getUuid(), propertyPaths);
186
//        Set<UUID> childrenUuids = new HashSet<>();
187
//
188
//
189
//        rootNode = CdmBase.deproxy(rootNode);
190
//        rootNode.removeNullValueFromChildren();
191
//        for (TaxonNode child: rootNode.getChildNodes()){
192
//            child = CdmBase.deproxy(child);
193
//            childrenUuids.add(child.getUuid());
194
//        }
195
//        Set<UUID> parentsNodesUUID = new HashSet<>(childrenUuids);
196
//        childrenUuids.clear();
197
//        List<TaxonNode> childrenNodes = new ArrayList<>();
198
//
199
//        findChildren(state, childrenUuids, parentsNodesUUID);
200

    
201
        IProgressMonitor monitor = state.getConfig().getProgressMonitor();
202
        @SuppressWarnings("unchecked")
203
        TaxonNodeOutStreamPartitioner<XmlExportState> partitioner
204
          = TaxonNodeOutStreamPartitioner.NewInstance(
205
                this, state, state.getConfig().getTaxonNodeFilter(),
206
                100, monitor, null);
207
        partitioner.setReadOnly(false);
208

    
209
            monitor.subTask("Start partitioning");
210
//            List<HashMap<String,String>> nameRecords = new ArrayList<>();
211
            TaxonNode node = partitioner.next();
212
            while (node != null){
213
              HashMap<String, String> nameRecord = createNewRecord(node, state);
214
              if (nameRecord != null){
215
                  nameRecords.add(nameRecord);
216
              }
217
              node = partitioner.next();
218
            }
219

    
220

    
221

    
222

    
223
//        List<HashMap<String,String>> nameRecords = new ArrayList<>();
224
//
225
//        childrenNodes = getTaxonNodeService().find(childrenUuids);
226
//        for(TaxonNode genusNode : childrenNodes)   {
227
//            nameRecords.add(createNewRecord(genusNode, state));
228
//            refreshTransaction();
229
//        }
230

    
231
        return nameRecords;
232

    
233
    }
234

    
235
//    /**
236
//     * @param state
237
//     * @param childrenUuids
238
//     * @param parentsNodesUUID
239
//     * @param familyNode
240
//     */
241
//    private void findChildren(CsvNameExportState state, Set<UUID> childrenUuids, Set<UUID> parentsNodesUUID) {
242
//        TaxonName name;
243
//        List<TaxonNode> familyNodes = getTaxonNodeService().find(parentsNodesUUID);
244
//        parentsNodesUUID =new HashSet<>();
245
//        for (TaxonNode familyNode: familyNodes){
246
//            familyNode = CdmBase.deproxy(familyNode);
247
//            familyNode.removeNullValueFromChildren();
248
//            for (TaxonNode child: familyNode.getChildNodes()){
249
//                child = CdmBase.deproxy(child);
250
//                Taxon taxon = CdmBase.deproxy(child.getTaxon());
251
//                if (taxon != null){
252
//                    name = CdmBase.deproxy(taxon.getName());
253
//                    if (child.getTaxon().getName().getRank().isLower(state.getConfig().getRank()) ) {
254
//                        childrenUuids.add(child.getUuid());
255
//                        if (child.hasChildNodes()){
256
//                            parentsNodesUUID.add(child.getUuid());
257
//                        }
258
//                    }else{
259
//                        parentsNodesUUID.add(child.getUuid());
260
//                    }
261
//                }
262
//            }
263
//            //refreshTransaction();
264
//            if (!parentsNodesUUID.isEmpty()){
265
//                findChildren(state, childrenUuids, parentsNodesUUID);
266
//            }
267
//        }
268
//
269
//    }
270

    
271

    
272

    
273

    
274
    private String createSynonymNameString(IBotanicalName synonymName, boolean isInvalid) {
275
        String synonymString = null;
276

    
277
        synonymString= createTaggedNameString(synonymName, isInvalid);
278
        Set<NameRelationship> nameRelations = synonymName.getNameRelations();
279

    
280
        INonViralName relatedName = null;
281
        String nameRelType = null;
282
        boolean first = true;
283
        boolean isInvalidRel = false;
284
        for (NameRelationship nameRel: nameRelations){
285
           // NameRelationship nameRel = nameRelations.iterator().next();
286
            if (!nameRel.getType().equals(NameRelationshipType.BASIONYM())){
287
                IBotanicalName fromName = CdmBase.deproxy(nameRel.getFromName());
288

    
289
                nameRel = CdmBase.deproxy(nameRel);
290
                nameRelType = nameRel.getType().getTitleCache();
291
                String relatedNameString = "";
292
                if (fromName.equals(synonymName)){
293
                    relatedName = nameRel.getToName();
294
                }else{
295
                    relatedName = nameRel.getFromName();
296
                }
297

    
298
                isInvalidRel = getStatus(relatedName);
299
                relatedNameString = createTaggedNameString(relatedName, isInvalidRel&&isInvalid);
300

    
301
                if (nameRel.getType().equals(NameRelationshipType.LATER_HOMONYM())){
302
                    if (synonymName.equals(nameRel.getFromName())){
303
                        if (first){
304
                            synonymString = synonymString + " [non " + relatedNameString ;
305
                            first = false;
306
                        } else{
307
                            synonymString = synonymString + " nec " + relatedNameString ;
308
                        }
309
                    }
310
                } else if (nameRel.getType().equals(NameRelationshipType.REPLACED_SYNONYM())){
311
                    //synonymString = synonymString + " [non " + relatedNameString + "]";
312
                } else if (nameRel.getType().equals(NameRelationshipType.BLOCKING_NAME_FOR())){
313
                    if (synonymName.equals(nameRel.getToName())){
314
                        if (first){
315
                            synonymString = synonymString + " [non " + relatedNameString ;
316
                            first = false;
317
                        } else{
318
                            synonymString = synonymString + " nec " + relatedNameString ;
319
                        }
320

    
321
                    }
322
                } else if (nameRel.getType().equals(NameRelationshipType.TREATED_AS_LATER_HOMONYM())){
323
                    if (first){
324
                        synonymString = synonymString + " [non " + relatedNameString ;
325
                        first = false;
326
                    } else{
327
                        synonymString = synonymString + " nec " + relatedNameString ;
328
                    }
329
                } else if (nameRel.getType().equals(NameRelationshipType.ALTERNATIVE_NAME())){
330
                    if (first){
331
                        synonymString = synonymString + " [non " + relatedNameString ;
332
                        first = false;
333
                    } else{
334
                        synonymString = synonymString + " nec " + relatedNameString ;
335
                    }
336
                } else if (nameRel.getType().equals(NameRelationshipType.CONSERVED_AGAINST())) {
337

    
338
                }else if (nameRel.getType().equals(NameRelationshipType.ORTHOGRAPHIC_VARIANT())){
339

    
340
                }
341
            }
342
        }
343
        if (!first){
344
            synonymString = synonymString + "]";
345
        }
346

    
347
        return synonymString;
348
    }
349

    
350
    /**
351
     * @param relatedName
352
     * @return
353
     */
354
    private boolean getStatus(INonViralName relatedName) {
355
        boolean result;
356
        if (!relatedName.getStatus().isEmpty()){
357
            NomenclaturalStatus status = CdmBase.deproxy(relatedName.getStatus().iterator().next());
358
            if (status.getType().isInvalid()){
359
                result = true;
360
            }else{
361
                result = false;
362
            }
363
        }else{
364
            result = false;
365
        }
366
        return result;
367
    }
368

    
369
    private String createTaggedNameString(INonViralName name, boolean isInvalid){
370
        String nameString = null;
371
        if (name == null){
372
            return nameString;
373
        }
374

    
375
        nameString = name.generateFullTitle();
376
        if (isInvalid){
377
            nameString = nameString.replace(name.getTitleCache(), "\""+name.getTitleCache()+"\"");
378
        }
379
        if (name.getGenusOrUninomial() != null){
380
            nameString = nameString.replaceAll(name.getGenusOrUninomial(), "<i>"+ name.getGenusOrUninomial() + "</i>");
381
        }
382
        if (name.getInfraGenericEpithet() != null){
383
            nameString = nameString.replaceAll(name.getInfraGenericEpithet(),  "<i>"+ name.getInfraGenericEpithet() + "</i>");
384
        }
385
        if (name.getSpecificEpithet() != null){
386
            nameString = nameString.replaceAll(name.getSpecificEpithet(),  "<i>"+ name.getSpecificEpithet() + "</i>");
387
        }
388
        if (name.getInfraSpecificEpithet() != null && !name.isAutonym()){
389
            nameString = nameString.replaceAll(name.getInfraSpecificEpithet(),  "<i>"+ name.getInfraSpecificEpithet() + "</i>");
390
        }
391

    
392
        return nameString;
393
    }
394

    
395

    
396

    
397
//    private List<TaxonNode> getGenusNodes (UUID classificationUUID){
398
//        Classification classification = getClassificationService().load(classificationUUID);
399
//        TaxonNode rootNode = classification.getRootNode();
400
//        rootNode = getTaxonNodeService().load(rootNode.getUuid());
401
//        Set<UUID> childrenUuids = new HashSet<>();
402
//
403
//        for (TaxonNode child: rootNode.getChildNodes()){
404
//            child = CdmBase.deproxy(child);
405
//            childrenUuids.add(child.getUuid());
406
//        }
407
//
408
//        List<TaxonNode> familyNodes = getTaxonNodeService().find(childrenUuids);
409
//        childrenUuids.clear();
410
//        List<TaxonNode> genusNodes = new ArrayList<>();
411
//        for (TaxonNode familyNode: familyNodes){
412
//            for (TaxonNode child: familyNode.getChildNodes()){
413
//                child = CdmBase.deproxy(child);
414
//                childrenUuids.add(child.getUuid());
415
//            }
416
//
417
//            genusNodes = getTaxonNodeService().find(childrenUuids);
418
//        }
419
//        return genusNodes;
420
//    }
421

    
422
    private TaxonNode getHigherNode(TaxonNode node, Rank rank){
423

    
424
        Rank nodeRank = node.getTaxon().getName().getRank();
425
        if (nodeRank.isKindOf(rank)){
426
            return null;
427

    
428
        }else if (nodeRank.isHigher(rank)){
429
            return null;
430
        } else {
431
            return node.getAncestorOfRank(rank);
432
        }
433
    }
434

    
435
    private void extractDescriptions(HashMap<String, String> nameRecord, Taxon taxon, Feature feature,
436
            String columnName, CsvNameExportState state){
437

    
438
        StringBuffer descriptionsString = new StringBuffer();
439
        TextData textElement;
440
        Set<Distribution> distributions = new HashSet<>();
441
        if (taxon.getDescriptions().isEmpty()){
442
            nameRecord.put(columnName, null);
443
                return;
444
        }
445
        for (DescriptionBase<?> descriptionBase: taxon.getDescriptions()){
446
            if (!descriptionBase.isImageGallery()){
447
                Set<DescriptionElementBase> elements = descriptionBase.getElements();
448
                for (DescriptionElementBase element: elements){
449
                    if (element.getFeature().equals(feature)){
450
                        if (element instanceof TextData){
451
                            textElement = CdmBase.deproxy(element, TextData.class);
452
                            descriptionsString.append(textElement.getText(Language.ENGLISH()));
453
                        }else if (element instanceof Distribution ){
454
                            Distribution distribution = CdmBase.deproxy(element, Distribution.class);
455
                            distributions.add(distribution);
456
                        }
457
                    }
458
                }
459
            }
460
        }
461
        if (state.getConfig().isCondensedDistribution()){
462
            List<Language> langs = new ArrayList<>();
463
            langs.add(Language.ENGLISH());
464

    
465
            //TODO add condensed distribution configuration to export configuration
466
            CondensedDistribution conDis = geoService.getCondensedDistribution(
467
                    distributions, true, null, CondensedDistributionConfiguration.NewCubaInstance(), langs );
468

    
469
            nameRecord.put(columnName, conDis.toString());
470

    
471
        } else{
472
            NamedArea area ;
473
            for (Distribution distribution:distributions){
474

    
475
                if (descriptionsString.length()> 0 ){
476
                    descriptionsString.append(", ");
477
                }
478
                area = CdmBase.deproxy(distribution.getArea());
479
                if (area.getIdInVocabulary() != null){
480
                    descriptionsString.append(area.getIdInVocabulary());
481
                }else if (area.getSymbol() != null){
482
                    descriptionsString.append(area.getSymbol());
483
                }else{
484
                    descriptionsString.append(area.getLabel());
485
                }
486

    
487
            }
488
            nameRecord.put(columnName, descriptionsString.toString());
489
        }
490

    
491
    }
492

    
493
    private Feature getNotesFeature(CsvNameExportState state){
494
        if (state.getNotesFeature() != null){
495
            return state.getNotesFeature();
496
        } else{
497
            Pager<Feature> notesFeature = getTermService().findByTitleWithRestrictions(Feature.class, "Notes" ,MatchMode.EXACT, null, null, null, null, null);
498
            if (notesFeature.getRecords().size() == 0){
499
                return null;
500
            }else{
501
                Feature feature=  notesFeature.getRecords().iterator().next();
502
                state.setNotesFeature(feature);
503
                return feature;
504
            }
505
        }
506

    
507
    }
508

    
509
    private HashMap<String, String> createNewRecord(TaxonNode childNode, CsvNameExportState state){
510
        HashMap<String, String> nameRecord = new HashMap<>();
511
        nameRecord.put("classification", childNode.getClassification().getTitleCache());
512
        if (!childNode.getTaxon().getName().getRank().isLower(Rank.GENUS())){
513
            return null;
514
        }
515
        TaxonNode familyNode = getHigherNode(childNode, Rank.FAMILY());
516
        Taxon taxon;
517
        String nameString;
518
        IBotanicalName name;
519
        if (familyNode == null){
520
            nameRecord.put("familyTaxon", null);
521
            nameRecord.put("familyName", null);
522
            nameRecord.put("descriptionsFam", null);
523
        }else{
524
            familyNode = CdmBase.deproxy(familyNode);
525
            familyNode.getTaxon().setProtectedTitleCache(true);
526
            nameRecord.put("familyTaxon", familyNode.getTaxon().getTitleCache());
527
            if (familyMap.get(familyNode.getTaxon().getUuid()) != null){
528
                nameRecord.putAll(familyMap.get(familyNode.getTaxon().getUuid()));
529
            }else{
530
                taxon = (Taxon)getTaxonService().load(familyNode.getTaxon().getUuid());
531
                taxon = CdmBase.deproxy(taxon);
532
                name = CdmBase.deproxy(taxon.getName());
533
                nameRecord.put("familyName", name.getNameCache());
534
                extractDescriptions(nameRecord, taxon, Feature.INTRODUCTION(), "descriptionsFam", state);
535
                familyMap.put(familyNode.getTaxon().getUuid(), nameRecord);
536
            }
537

    
538
        }
539
        TaxonNode genusNode = getHigherNode(childNode, Rank.GENUS());
540
        if (genusNode!= null){
541
            genusNode = CdmBase.deproxy(genusNode);
542
            genusNode.getTaxon().setProtectedTitleCache(true);
543
            nameRecord.put("genusTaxon", genusNode.getTaxon().getTitleCache());
544
            if (genusMap.get(genusNode.getTaxon().getUuid()) != null){
545
                nameRecord.putAll(genusMap.get(genusNode.getTaxon().getUuid()));
546
            }else{
547
                taxon = (Taxon)getTaxonService().load(genusNode.getTaxon().getUuid());
548
                taxon = CdmBase.deproxy(taxon);
549
                name = CdmBase.deproxy(taxon.getName());
550
                if (name.getNameCache() != null){
551
                    nameRecord.put("genusName", name.getNameCache());
552
                }else{
553
                    nameRecord.put("genusName", name.getGenusOrUninomial());
554
                }
555
                extractDescriptions(nameRecord, taxon,getNotesFeature(state), "descriptionsGen", state);
556
                genusMap.put(genusNode.getTaxon().getUuid(), nameRecord);
557
            }
558

    
559

    
560
        }else{
561
            nameRecord.put("genusTaxon", null);
562
            nameRecord.put("genusName", null);
563
            nameRecord.put("descriptionsGen", null);
564
        }
565

    
566
//        taxon = (Taxon) getTaxonService().load(childNode.getTaxon().getUuid());
567
        taxon = CdmBase.deproxy(childNode.getTaxon());
568
        //  if (taxon.isPublish()){
569

    
570
        INonViralName nonViralName = taxon.getName();
571

    
572
        nameString = createTaggedNameString(nonViralName, false);
573
        nameRecord.put("childTaxon", taxon.getTitleCache());
574
        if (taxon.getSec()!= null){
575
            nameRecord.put("secRef", taxon.getSec().getTitleCache());
576
        }else{
577
            nameRecord.put("secRef", null);
578
        }
579

    
580
        getTaxonRelations(nameRecord, taxon);
581

    
582
        name = CdmBase.deproxy(taxon.getName());
583
        nameRecord.put("childName",nameString);
584
        nameRecord.put("nameId", String.valueOf(name.getId()));
585
        nameRecord.put("nameCache", name.getNameCache());
586
        nameRecord.put("titleName", name.getTitleCache());
587
        if (name.getNomenclaturalReference() != null){
588
            nameRecord.put("NomRefTitleCache", name.getNomenclaturalReference().getTitleCache());
589
        } else{
590
            nameRecord.put("NomRefTitleCache",null);
591
        }
592
        nameRecord.put("fullName", name.getNameCache());
593
        nameRecord.put("fullTitleCache",  name.getFullTitleCache());
594
        Set<TypeDesignationBase> typeDesSet =  name.getTypeDesignations();
595
        Iterator<TypeDesignationBase> it = typeDesSet.iterator();
596
        String typeNameString = NOT_DESIGNATED;
597
        String statusString = null;
598
        if (it.hasNext()){
599

    
600
            TypeDesignationBase<?> typeDes = CdmBase.deproxy(it.next());
601

    
602
            if (typeDes instanceof NameTypeDesignation){
603
                NameTypeDesignation nameTypeDes = CdmBase.deproxy(typeDes, NameTypeDesignation.class);
604

    
605
                IBotanicalName typeName =  CdmBase.deproxy(nameTypeDes.getTypeName());
606
                if (typeName != null){
607

    
608
                    typeNameString = "<i>" + typeName.getNameCache() +"</i> "  + typeName.getAuthorshipCache();
609
                    if (nameTypeDes.getTypeStatus() != null){
610
                        NameTypeDesignationStatus status = CdmBase.deproxy(nameTypeDes.getTypeStatus());
611
                        statusString = status.getTitleCache();
612
                    }
613
                }
614
            }
615
        }
616
        nameRecord.put("typeName", typeNameString);
617
        StringBuffer homotypicalSynonyms = new StringBuffer();
618
        TreeMap<HomotypicalGroup,List<Synonym>> heterotypicSynonymsList = new TreeMap<>(new HomotypicalGroupComparator());
619

    
620
        List<Synonym> homotypicSynonymsList = new ArrayList<>();
621
        StringBuffer heterotypicalSynonyms = new StringBuffer();
622
        List<Synonym> homotypicSynonyms;
623

    
624
        HomotypicalGroup group;
625
        IBotanicalName synonymName;
626
        String doubtfulTitleCache;
627
        for (Synonym synonym: taxon.getSynonyms()){
628
            synonymName = CdmBase.deproxy(synonym.getName());
629
            group = CdmBase.deproxy(synonymName.getHomotypicalGroup());
630
            synonymName.generateFullTitle();
631
            if (synonym.isDoubtful()){
632
                if (!synonymName.getFullTitleCache().startsWith("?")){
633
                    doubtfulTitleCache = "?" + synonymName.getFullTitleCache();
634
                    synonymName = synonymName.clone();
635
                    synonymName.setFullTitleCache(doubtfulTitleCache, true);
636
                }
637
            }
638
            if (!group.equals(name.getHomotypicalGroup())){
639
                if (heterotypicSynonymsList.containsKey(group)){
640
                    heterotypicSynonymsList.get(group).add(synonym);
641
                }else{
642
                    homotypicSynonyms = new ArrayList<>();
643
                    homotypicSynonyms.add(synonym);
644
                    heterotypicSynonymsList.put(group, homotypicSynonyms);
645
                    homotypicSynonyms= null;
646
                }
647
            } else{
648
                synonymName.generateFullTitle();
649
                homotypicSynonymsList.add(synonym);
650
            }
651
        }
652

    
653

    
654

    
655
        String synonymString;
656
        boolean first = true;
657

    
658
        for (List<Synonym> list: heterotypicSynonymsList.values()){
659
            Collections.sort(list, new HomotypicGroupTaxonComparator(null));
660
            first = true;
661
            for (TaxonBase<?> synonym : list){
662
                NomenclaturalStatus status = null;
663
                if (!synonym.getName().getStatus().isEmpty()){
664
                    status = CdmBase.deproxy(synonym.getName().getStatus().iterator().next());
665
                    if (status.getType().isInvalid()){
666
                        heterotypicalSynonyms.append(" <invalid> ");
667
                        synonymName = CdmBase.deproxy(synonym.getName());
668

    
669
                        synonymString = createSynonymNameString(synonymName, state.getConfig().isInvalidNamesQuoted()) ;
670
                        heterotypicalSynonyms.append(synonymString);
671
                        continue;
672
                    }
673
                }
674
                if (first){
675
                    heterotypicalSynonyms.append(" <heterotypic> ");
676
                }else{
677
                    heterotypicalSynonyms.append(" <homonym> ");
678
                }
679
                first = false;
680
                synonymName = CdmBase.deproxy(synonym.getName());
681
                synonymString = createSynonymNameString(synonymName, false);
682
                heterotypicalSynonyms.append(synonymString);
683
            }
684
        }
685

    
686
        first = true;
687
        Collections.sort(homotypicSynonymsList, new HomotypicGroupTaxonComparator(null)  );
688
        NomenclaturalStatus status = null;
689
        for (TaxonBase<?> synonym : homotypicSynonymsList){
690

    
691
            if (!synonym.getName().getStatus().isEmpty()){
692
                status = CdmBase.deproxy(synonym.getName().getStatus().iterator().next());
693
                if (status.getType().isInvalid()){
694
                    homotypicalSynonyms.append(" <invalid> ");
695
                    synonymName = CdmBase.deproxy(synonym.getName());
696
                    synonymString = createSynonymNameString(synonymName, true);
697
                    homotypicalSynonyms.append(synonymString);
698
                    continue;
699
                }else if (!first){
700
                    homotypicalSynonyms.append(" <homonym> ");
701
                }
702

    
703
            }else if (!first){
704
                homotypicalSynonyms.append(" <homonym> ");
705
            }
706
            first = false;
707
            synonymName = CdmBase.deproxy(synonym.getName());
708

    
709
            synonymString = createSynonymNameString(synonymName, false);
710

    
711
            homotypicalSynonyms.append(synonymString);
712

    
713
        }
714

    
715
        nameRecord.put("synonyms_homotypic", homotypicalSynonyms.toString());
716
        nameRecord.put("synonyms_heterotypic", heterotypicalSynonyms.toString());
717
        nameRecord.put("status", statusString);
718

    
719
        Set<NameRelationship> nameRelations = name.getNameRelations();
720

    
721
        INonViralName relatedName = null;
722
        String nameRelType = null;
723
        String relNameString = null;
724
        if (nameRelations.size()>0){
725
            NameRelationship nameRel = nameRelations.iterator().next();
726
            IBotanicalName fromName = CdmBase.deproxy(nameRel.getFromName());
727
            if (fromName.equals(taxon.getName())){
728
                relatedName = nameRel.getToName();
729

    
730
            }else{
731
                relatedName = nameRel.getFromName();
732
            }
733
            nameRel = CdmBase.deproxy(nameRel);
734
            nameRelType = nameRel.getType().getTitleCache();
735
            relNameString  = createTaggedNameString(relatedName, getStatus(relatedName));
736
        }
737

    
738

    
739
        nameRecord.put("relatedName", relNameString);
740
        nameRecord.put("nameRelType", nameRelType);
741

    
742
        extractDescriptions(nameRecord, taxon, Feature.DISTRIBUTION(), "descriptions", state);
743
        return nameRecord;
744
    }
745

    
746
    /**
747
     * @param nameRecord
748
     * @param taxon
749
     */
750
    private void getTaxonRelations(HashMap<String, String> nameRecord, Taxon taxon) {
751
        Set<TaxonRelationship> relations = new HashSet<>();
752
        relations =taxon.getTaxonRelations();
753
        if (relations.isEmpty()){
754
            nameRecord.put("missappliedNames", null);
755
        }else{
756
            Taxon relatedTaxon = null;
757
            StringBuffer nameString = new StringBuffer();
758
            for (TaxonRelationship rel : relations){
759
                if (rel.getType().isAnyMisappliedName()){
760
                    relatedTaxon = rel.getFromTaxon();
761
                    Reference secRef = relatedTaxon.getSec();
762
                    String appendedPhrase = "";
763
                    if (relatedTaxon.getAppendedPhrase() != null){
764
                        appendedPhrase = relatedTaxon.getAppendedPhrase();
765
                    }
766
                    if (appendedPhrase.equals("sphalm.")){
767
                        String relNameString  = createTaggedNameString(relatedTaxon.getName(), getStatus(relatedTaxon.getName()));
768

    
769
                        nameRecord.put("relatedName", relNameString);
770
                        nameRecord.put("nameRelType", NameRelationshipType.ORTHOGRAPHIC_VARIANT().getTitleCache());
771
                        return;
772
                    }
773
                    if (secRef == null){
774
                        nameString.append("<misapplied>" +"\u201C" + createTaggedNameString(relatedTaxon.getName(), false) + "\u201D " + appendedPhrase);
775
                    } else if (secRef.getAuthorship() == null){
776
                        nameString.append("<misapplied>"+"\u201C" + createTaggedNameString(relatedTaxon.getName(), false) + "\u201D " + appendedPhrase + " sensu " + secRef.getTitleCache());
777
                    } else {
778
                        nameString.append("<misapplied>\"" + createTaggedNameString(relatedTaxon.getName(), false) + "\" " + appendedPhrase + " sensu " + secRef.getAuthorship().getFullTitle());
779
                    }
780

    
781
                }
782
            }
783
            nameRecord.put("missappliedNames", nameString.toString());
784
        }
785
    }
786

    
787
}
788

    
(1-1/5)