Project

General

Profile

Download (14.7 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.api.service.dto;
10

    
11
import java.util.ArrayList;
12
import java.util.Arrays;
13
import java.util.Collection;
14
import java.util.HashSet;
15
import java.util.List;
16
import java.util.Map;
17
import java.util.Set;
18
import java.util.UUID;
19

    
20
import org.apache.commons.lang3.StringUtils;
21
import org.apache.logging.log4j.LogManager;
22
import org.apache.logging.log4j.Logger;
23
import org.joda.time.DateTime;
24

    
25
import eu.etaxonomy.cdm.api.service.exception.RegistrationValidationException;
26
import eu.etaxonomy.cdm.api.service.name.TypeDesignationDTO;
27
import eu.etaxonomy.cdm.api.service.name.TypeDesignationSetFormatter;
28
import eu.etaxonomy.cdm.api.service.name.TypeDesignationSetManager;
29
import eu.etaxonomy.cdm.api.service.name.TypeDesignationWorkingSet;
30
import eu.etaxonomy.cdm.format.reference.NomenclaturalSourceFormatter;
31
import eu.etaxonomy.cdm.model.common.VerbatimTimePeriod;
32
import eu.etaxonomy.cdm.model.common.VersionableEntity;
33
import eu.etaxonomy.cdm.model.name.NameTypeDesignation;
34
import eu.etaxonomy.cdm.model.name.Registration;
35
import eu.etaxonomy.cdm.model.name.RegistrationStatus;
36
import eu.etaxonomy.cdm.model.name.TaxonName;
37
import eu.etaxonomy.cdm.model.name.TypeDesignationBase;
38
import eu.etaxonomy.cdm.model.reference.INomenclaturalReference;
39
import eu.etaxonomy.cdm.model.reference.NamedSourceBase;
40
import eu.etaxonomy.cdm.model.reference.Reference;
41
import eu.etaxonomy.cdm.model.reference.ReferenceType;
42
import eu.etaxonomy.cdm.ref.EntityReference;
43
import eu.etaxonomy.cdm.ref.TypedEntityReference;
44
import eu.etaxonomy.cdm.strategy.cache.TagEnum;
45
import eu.etaxonomy.cdm.strategy.cache.TaggedCacheHelper;
46
import eu.etaxonomy.cdm.strategy.cache.TaggedText;
47

    
48
public class RegistrationDTO {
49

    
50
    private static final Logger logger = LogManager.getLogger(RegistrationDTO.class);
51

    
52
    private String summary = "";
53

    
54
    private RegistrationType registrationType;
55

    
56
    private Reference citation = null;
57

    
58
    private String citationDetail = null;
59

    
60
    private String submitterUserName = null;
61

    
62
    private EntityReference name = null;
63

    
64
    private TypeDesignationSetManager typeDesignationManager;
65

    
66
    private Registration reg;
67

    
68
    private List<String> validationProblems = new ArrayList<>();
69

    
70
    private Set<TypedEntityReference<Registration>> blockedBy;
71

    
72
    private List<TaggedText> summaryTaggedText = new ArrayList<>();
73

    
74
    private String nomenclaturalCitationString;
75

    
76
    private String bibliographicCitationString;
77

    
78
    private String bibliographicInRefCitationString;
79

    
80
    /**
81
     * @param reg
82
     * @param typifiedName should be provided for registrations for TypeDesignations
83
     * @throws RegistrationValidationException
84
     */
85
    public RegistrationDTO(Registration reg) {
86

    
87
         this.reg = reg;
88

    
89
         registrationType = RegistrationType.from(reg);
90

    
91
         if(reg.getSubmitter() != null ){
92
             submitterUserName = reg.getSubmitter().getUsername();
93
         }
94

    
95
         if(hasName(reg)){
96
             name = new EntityReference(reg.getName().getUuid(), reg.getName().getTitleCache());
97
         }
98
        NamedSourceBase publishedUnit = findPublishedUnit(reg);
99
        if(publishedUnit != null) {
100
            citation = publishedUnit.getCitation();
101
            citationDetail = publishedUnit.getCitationMicroReference();
102
        }
103

    
104
        switch (registrationType) {
105
        case EMPTY:
106
            summary = "BLANK REGISTRATION";
107
            summaryTaggedText.addAll(Arrays.asList(new TaggedText(TagEnum.label, summary)));
108
            break;
109
        case NAME:
110
            summary = reg.getName().getTitleCache();
111
            summaryTaggedText.addAll(reg.getName().getTaggedName());
112
            break;
113
        case NAME_AND_TYPIFICATION:
114
        case TYPIFICATION:
115
        default:
116
            try {
117
                typeDesignationManager = new TypeDesignationSetManager(reg.getTypeDesignations());
118
                summaryTaggedText.addAll(new TypeDesignationSetFormatter(false, true, true)
119
                        .toTaggedText(typeDesignationManager));
120
                summary = TaggedCacheHelper.createString(summaryTaggedText);
121
            } catch (RegistrationValidationException e) {
122
                validationProblems.add("Validation errors: " + e.getMessage());
123
            }
124
            break;
125
        }
126

    
127
        makeBibliographicCitationStrings();
128
        makeNomenclaturalCitationString();
129
    }
130

    
131
    /**
132
     * To create an initially empty DTO for which only the <code>typifiedName</code> and the <code>publication</code> are defined.
133
     * All TypeDesignations added to the <code>Registration</code> need to refer to the same <code>typifiedName</code> and must be
134
     * published in the same <code>publication</code>.
135
     *
136
     * @param reg
137
     * @param typifiedName
138
     */
139
    public RegistrationDTO(Registration reg, TaxonName typifiedName, Reference publication) {
140
        this.reg = reg;
141
        citation = publication;
142
        // create a TypeDesignationSetManager with only a reference to the typifiedName for validation
143
        typeDesignationManager = new TypeDesignationSetManager(typifiedName);
144
        makeBibliographicCitationStrings();
145
        makeNomenclaturalCitationString();
146
    }
147

    
148
    public static NamedSourceBase findPublishedUnit(Registration reg) {
149
        NamedSourceBase publishedUnit = null;
150
        if(hasName(reg)){
151
            publishedUnit = reg.getName().getNomenclaturalSource();
152
        } else if(hasTypifications(reg)){
153
            if(!reg.getTypeDesignations().isEmpty()){
154
                for(TypeDesignationBase<?> td : reg.getTypeDesignations()){
155
                    if(td.getDesignationSource() != null) {
156
                        publishedUnit = td.getDesignationSource();
157
                    }
158
                }
159
            }
160
        }
161
        return publishedUnit;
162
    }
163

    
164
    private static boolean hasTypifications(Registration reg) {
165
        return reg.getTypeDesignations() != null && reg.getTypeDesignations().size() > 0;
166
    }
167

    
168
    private static boolean hasName(Registration reg) {
169
        return reg.getName() != null;
170
    }
171

    
172
    /**
173
     * Provides access to the Registration entity this DTO has been build from.
174
     * This method is purposely not a getter to hide the original Registration
175
     * from generic processes which are exposing, binding bean properties.
176
     *IReference
177
     * @return
178
     */
179
    public Registration registration() {
180
        return reg;
181
    }
182

    
183
    public String getSummary() {
184
        return summary;
185
    }
186

    
187
    public List<TaggedText> getSummaryTaggedText() {
188
        return summaryTaggedText;
189
    }
190

    
191
    public String getSubmitterUserName(){
192
        return submitterUserName;
193
    }
194

    
195
    public RegistrationType getRegistrationType() {
196
        return registrationType;
197
    }
198

    
199
    public RegistrationStatus getStatus() {
200
        return reg.getStatus();
201
    }
202

    
203
    public String getIdentifier() {
204
        return reg.getIdentifier();
205
    }
206

    
207
    public UUID getUuid() {
208
        return reg.getUuid();
209
    }
210

    
211
    public String getSpecificIdentifier() {
212
        return reg.getSpecificIdentifier();
213
    }
214

    
215
    public DateTime getRegistrationDate() {
216
        return reg.getRegistrationDate();
217
    }
218

    
219
    public String getInstitutionTitleCache(){
220
        return reg.getInstitution() != null ? reg.getInstitution().getName() : null;
221
    }
222

    
223
    public VerbatimTimePeriod getDatePublished() {
224
        return citation == null ? null : citation.getDatePublished();
225
    }
226

    
227
    public DateTime getCreated() {
228
        return reg.getCreated();
229
    }
230

    
231
    public Reference getCitation() {
232
        return citation;
233
    }
234

    
235
    public void setCitation(Reference citation) throws Exception {
236
        if(this.citation == null){
237
            this.citation = citation;
238
        } else {
239
            throw new Exception("Can not set the citation on a non emtpy RegistrationDTO");
240
        }
241
        makeBibliographicCitationStrings();
242
        makeNomenclaturalCitationString();
243
    }
244

    
245
    public UUID getCitationUuid() {
246
        return citation == null ? null : citation.getUuid();
247
    }
248

    
249
    public EntityReference getTypifiedNameRef() {
250
        return typeDesignationManager != null ? typeDesignationManager.getTypifiedNameAsEntityRef() : null;
251
    }
252

    
253
    public TaxonName typifiedName() {
254
        return typeDesignationManager != null ? typeDesignationManager.getTypifiedName() : null;
255
    }
256

    
257
    public EntityReference getNameRef() {
258
        return name;
259
    }
260

    
261
    public Map<TypedEntityReference<? extends VersionableEntity>, TypeDesignationWorkingSet> getOrderedTypeDesignationWorkingSets() {
262
        return typeDesignationManager != null ? typeDesignationManager.getOrderedTypeDesignationWorkingSets() : null;
263
    }
264

    
265
    public TypeDesignationWorkingSet getTypeDesignationWorkingSet(TypedEntityReference baseEntityReference) {
266
        return typeDesignationManager != null ? typeDesignationManager.getOrderedTypeDesignationWorkingSets().get(baseEntityReference) : null;
267
    }
268

    
269
    public Set<TypeDesignationBase> getTypeDesignationsInWorkingSet(TypedEntityReference baseEntityReference) {
270
        Set<TypeDesignationBase> typeDesignations = new HashSet<>();
271
        TypeDesignationWorkingSet workingSet = getTypeDesignationWorkingSet(baseEntityReference);
272
        for(TypeDesignationDTO<?> ref :  workingSet.getTypeDesignations()){
273
            typeDesignations.add(findTypeDesignation(ref));
274
        }
275
        return typeDesignations;
276
    }
277

    
278
    public NameTypeDesignation getNameTypeDesignation(TypedEntityReference baseEntityReference) {
279
        Set<TypeDesignationBase> typeDesignations = getTypeDesignationsInWorkingSet(baseEntityReference);
280
        if(typeDesignations.size() == 1){
281
            TypeDesignationBase<?> item = typeDesignations.iterator().next();
282
            return (NameTypeDesignation)item ;
283
        }
284
        if(typeDesignations.size() == 0){
285
            return null;
286
        }
287
        if(typeDesignations.size() > 1){
288
            throw new RuntimeException("Workingsets of NameTypeDesignations must contain exactly one item.");
289
        }
290
        return null;
291
    }
292

    
293
    private TypeDesignationBase<?> findTypeDesignation(TypeDesignationDTO ref) {
294
        return typeDesignationManager != null ? typeDesignationManager.findTypeDesignation(ref.getUuid()) : null;
295
    }
296

    
297
    public Collection<TypeDesignationBase<?>> typeDesignations() {
298
        return typeDesignationManager != null ? typeDesignationManager.getTypeDesignations() : null;
299
    }
300

    
301
    private void makeNomenclaturalCitationString() {
302
        if(citation == null){
303
            nomenclaturalCitationString = null;
304
        } else {
305
            if(INomenclaturalReference.class.isAssignableFrom(citation.getClass())){
306
                nomenclaturalCitationString = NomenclaturalSourceFormatter.INSTANCE().format(citation, citationDetail);
307
            } else {
308
                logger.error("The citation is not a NomenclaturalReference");
309
                nomenclaturalCitationString = citation.generateTitle();
310
            }
311
        }
312
    }
313

    
314
    private void makeBibliographicCitationStrings() {
315
        if(citation == null){
316
            bibliographicCitationString = null;
317
        } else {
318
            Reference bibliographicCitation;
319
            String bibliographicCitationDetail = citationDetail;
320
            if((citation.getType() == ReferenceType.Section || citation.getType() == ReferenceType.BookSection) && citation.getInReference() != null){
321
                bibliographicCitation = citation.getInReference();
322
                bibliographicCitationDetail = null; // can possibly be known once https://dev.e-taxonomy.eu/redmine/issues/6623 is solved
323
            } else {
324
                bibliographicCitation = citation;
325
            }
326
            if(StringUtils.isNotEmpty(bibliographicCitationDetail)){
327
                // TODO see https://dev.e-taxonomy.eu/redmine/issues/6623
328
                bibliographicInRefCitationString = bibliographicCitation.generateTitle().replaceAll("\\.$", "") + (StringUtils.isNotEmpty(bibliographicCitationDetail) ? ": " + bibliographicCitationDetail : "");
329
            } else {
330
                bibliographicInRefCitationString = bibliographicCitation.generateTitle();
331
            }
332
            if(StringUtils.isNotEmpty(citationDetail)){
333
                // TODO see https://dev.e-taxonomy.eu/redmine/issues/6623
334
                bibliographicCitationString = citation.generateTitle().replaceAll("\\.$", "") + (StringUtils.isNotEmpty(citationDetail) ? ": " + citationDetail : "");
335
            } else {
336
                bibliographicCitationString = citation.generateTitle();
337
            }
338
        }
339
    }
340

    
341
    /**
342
     * The nomenclatural citation is always the nomenclaturalCitation of the reference which is directly
343
     * associated with the registration.
344
     * <p>
345
     * <b>Note:</b>Compare with {@link #getBibliographicCitationString()}
346
     *
347
     * @return the nomenclaturalCitationString
348
     */
349
    public String getNomenclaturalCitationString() {
350
        return nomenclaturalCitationString;
351
    }
352

    
353
    /**
354
     * The bibliographic in-reference citation is either taken from the reference which is directly
355
     * associated with the registration. In case this reference is a {@link eu.etaxonomy.cdm.model.reference.ReferenceType#Section} or
356
     * {@link eu.etaxonomy.cdm.model.reference.ReferenceType#BookSection} the inReference will be taken instead.
357
     * <p>
358
     * <b>Note:</b>Compare with {@link #getBibliographicCitationString()}
359
     *
360
     * @return the bibliographicInRefCitationString
361
     */
362
    public String getBibliographicInRefCitationString() {
363
       return bibliographicInRefCitationString;
364
    }
365

    
366
    /**
367
     * The bibliographic citation is either reference which is directly
368
     * associated with the registration.
369
     * <p>
370
     * <b>Note:</b>Compare with {@link #getBibliographicInRefCitationString()}
371
     *
372
     * @return the bibliographicCitationString
373
     */
374
    public String getBibliographicCitationString() {
375
        return bibliographicCitationString;
376
    }
377

    
378
    public boolean isBlocked() {
379
        return reg.getBlockedBy() != null && !reg.getBlockedBy().isEmpty();
380
    }
381

    
382
    /**
383
     * @return the blockedBy
384
     */
385
    public Set<TypedEntityReference<Registration>> getBlockedBy() {
386

    
387
        if(blockedBy == null){
388
            blockedBy = new HashSet<>();
389
            if(reg.getBlockedBy() != null){
390
                for(Registration blockReg : reg.getBlockedBy()){
391
                    blockedBy.add(new TypedEntityReference<Registration>(Registration.class, blockReg.getUuid(), blockReg.getIdentifier()));
392
                }
393
            }
394
        }
395
        return blockedBy;
396
    }
397

    
398
    public List<String> getValidationProblems() {
399
        return validationProblems;
400
    }
401

    
402
    public boolean isPersisted() {
403
        return reg.isPersited();
404
    }
405
}
(29-29/46)