ref #6682 fix misapplication deduplication issues
[cdmlib.git] / cdmlib-services / src / main / java / eu / etaxonomy / cdm / api / service / dto / RegistrationDTO.java
1 /**
2 * Copyright (C) 2017 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
8 */
9 package eu.etaxonomy.cdm.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.LinkedHashMap;
16 import java.util.List;
17 import java.util.Set;
18 import java.util.UUID;
19
20 import org.apache.commons.lang3.StringUtils;
21 import org.apache.log4j.Logger;
22 import org.joda.time.DateTime;
23
24 import eu.etaxonomy.cdm.api.service.exception.RegistrationValidationException;
25 import eu.etaxonomy.cdm.api.service.name.TypeDesignationSetManager;
26 import eu.etaxonomy.cdm.api.service.name.TypeDesignationSetManager.TypeDesignationWorkingSet;
27 import eu.etaxonomy.cdm.model.common.VerbatimTimePeriod;
28 import eu.etaxonomy.cdm.model.name.NameTypeDesignation;
29 import eu.etaxonomy.cdm.model.name.Registration;
30 import eu.etaxonomy.cdm.model.name.RegistrationStatus;
31 import eu.etaxonomy.cdm.model.name.TaxonName;
32 import eu.etaxonomy.cdm.model.name.TypeDesignationBase;
33 import eu.etaxonomy.cdm.model.reference.INomenclaturalReference;
34 import eu.etaxonomy.cdm.model.reference.Reference;
35 import eu.etaxonomy.cdm.ref.EntityReference;
36 import eu.etaxonomy.cdm.ref.TypedEntityReference;
37 import eu.etaxonomy.cdm.strategy.cache.TagEnum;
38 import eu.etaxonomy.cdm.strategy.cache.TaggedText;
39
40 public class RegistrationDTO{
41
42 private static final Logger logger = Logger.getLogger(RegistrationDTO.class);
43
44 private String summary = "";
45
46 private RegistrationType registrationType;
47
48 private Reference citation = null;
49
50 private String citationDetail = null;
51
52 private String submitterUserName = null;
53
54 private EntityReference name = null;
55
56 private TypeDesignationSetManager typeDesignationManager;
57
58 private Registration reg;
59
60 private List<String> validationProblems = new ArrayList<>();
61
62 private Set<TypedEntityReference<Registration>> blockedBy;
63
64 private List<TaggedText> summaryTaggedText;
65
66
67 /**
68 * @param reg
69 * @param typifiedName should be provided in for Registrations for TypeDesignations
70 * @throws RegistrationValidationException
71 */
72 public RegistrationDTO(Registration reg) {
73
74 this.reg = reg;
75
76 registrationType = RegistrationType.from(reg);
77
78 if(reg.getSubmitter() != null ){
79 submitterUserName = reg.getSubmitter().getUsername();
80 }
81
82 if(hasName(reg)){
83 citation = reg.getName().getNomenclaturalReference();
84 citationDetail = reg.getName().getNomenclaturalMicroReference();
85 name = new EntityReference(reg.getName().getUuid(), reg.getName().getTitleCache());
86 }
87 if(hasTypifications(reg)){
88 if(!reg.getTypeDesignations().isEmpty()){
89 for(TypeDesignationBase td : reg.getTypeDesignations()){
90 if(citation == null) {
91 citation = td.getCitation();
92 citationDetail = td.getCitationMicroReference();
93 }
94 }
95 }
96 }
97 switch(registrationType) {
98 case EMPTY:
99 summary = "BLANK REGISTRATION";
100 summaryTaggedText = Arrays.asList(new TaggedText(TagEnum.label, summary));
101 break;
102 case NAME:
103 summary = reg.getName().getTitleCache();
104 summaryTaggedText = reg.getName().getTaggedName();
105 break;
106 case NAME_AND_TYPIFICATION:
107 case TYPIFICATION:
108 default:
109 try {
110 typeDesignationManager = new TypeDesignationSetManager(reg.getTypeDesignations());
111 summary = typeDesignationManager.print();
112 summaryTaggedText = typeDesignationManager.toTaggedText();
113 } catch (RegistrationValidationException e) {
114 validationProblems.add("Validation errors: " + e.getMessage());
115 }
116 break;
117 }
118
119 // trigger initialization of the reference
120 getNomenclaturalCitationString();
121
122 }
123
124 /**
125 * To create an initially empty DTO for which only the <code>typifiedName</code> and the <code>publication</code> are defined.
126 * All TypeDesignations added to the <code>Registration</code> need to refer to the same <code>typifiedName</code> and must be
127 * published in the same <code>publication</code>.
128 *
129 * @param reg
130 * @param typifiedName
131 */
132 public RegistrationDTO(Registration reg, TaxonName typifiedName, Reference publication) {
133 this.reg = reg;
134 citation = publication;
135 // create a TypeDesignationSetManager with only a reference to the typifiedName for validation
136 typeDesignationManager = new TypeDesignationSetManager(typifiedName);
137 }
138
139 /**
140 * @param reg
141 * @return
142 */
143 private boolean hasTypifications(Registration reg) {
144 return reg.getTypeDesignations() != null && reg.getTypeDesignations().size() > 0;
145 }
146
147 /**
148 * @param reg
149 * @return
150 */
151 private boolean hasName(Registration reg) {
152 return reg.getName() != null;
153 }
154
155
156 /**
157 * Provides access to the Registration entity this DTO has been build from.
158 * This method is purposely not a getter to hide the original Registration
159 * from generic processes which are exposing, binding bean properties.
160 *IReference
161 * @return
162 */
163 public Registration registration() {
164 return reg;
165 }
166
167
168 /**
169 * @return the summary
170 */
171 public String getSummary() {
172 return summary;
173 }
174
175 /**
176 * @return the summary
177 */
178 public List<TaggedText> getSummaryTaggedText() {
179 return summaryTaggedText;
180 }
181
182 public String getSubmitterUserName(){
183 return submitterUserName;
184 }
185
186 /**
187 * @return the registrationType
188 */
189 public RegistrationType getRegistrationType() {
190 return registrationType;
191 }
192
193 /**
194 * @return the status
195 */
196 public RegistrationStatus getStatus() {
197 return reg.getStatus();
198 }
199
200 /**
201 * @return the identifier
202 */
203 public String getIdentifier() {
204 return reg.getIdentifier();
205 }
206
207
208 public UUID getUuid() {
209 return reg.getUuid();
210 }
211
212 /**
213 * @return the specificIdentifier
214 */
215 public String getSpecificIdentifier() {
216 return reg.getSpecificIdentifier();
217 }
218
219 /**
220 * @return the registrationDate
221 */
222 public DateTime getRegistrationDate() {
223 return reg.getRegistrationDate();
224 }
225
226 /**
227 * @return the registrationDate
228 */
229 public VerbatimTimePeriod getDatePublished() {
230 return citation == null ? null : citation.getDatePublished();
231 }
232
233 /**
234 * @return the created
235 */
236 public DateTime getCreated() {
237 return reg.getCreated();
238 }
239
240 public Reference getCitation() {
241 return citation;
242 }
243
244 public void setCitation(Reference citation) throws Exception {
245 if(this.citation == null){
246 this.citation = citation;
247 } else {
248 throw new Exception("Can not set the citation on a non emtpy RegistrationDTO");
249 }
250 }
251
252
253 public UUID getCitationUuid() {
254 return citation == null ? null : citation.getUuid();
255 }
256
257 public EntityReference getTypifiedNameRef() {
258 return typeDesignationManager != null ? typeDesignationManager.getTypifiedNameRef() : null;
259 }
260
261 public TaxonName getTypifiedName() {
262 return typeDesignationManager != null ? typeDesignationManager.getTypifiedName() : null;
263 }
264
265 public EntityReference getNameRef() {
266 return name;
267 }
268
269 public LinkedHashMap<TypedEntityReference, TypeDesignationWorkingSet> getOrderdTypeDesignationWorkingSets() {
270 return typeDesignationManager != null ? typeDesignationManager.getOrderdTypeDesignationWorkingSets() : null;
271 }
272
273 /**
274 * @param baseEntityReference
275 */
276 public TypeDesignationWorkingSet getTypeDesignationWorkingSet(TypedEntityReference baseEntityReference) {
277 return typeDesignationManager != null ? typeDesignationManager.getOrderdTypeDesignationWorkingSets().get(baseEntityReference) : null;
278
279 }
280
281 /**
282 * @param baseEntityReference
283 */
284 public Set<TypeDesignationBase> getTypeDesignationsInWorkingSet(TypedEntityReference baseEntityReference) {
285 Set<TypeDesignationBase> typeDesignations = new HashSet<>();
286 TypeDesignationWorkingSet workingSet = getTypeDesignationWorkingSet(baseEntityReference);
287 for(EntityReference ref : workingSet.getTypeDesignations()){
288 typeDesignations.add(findTypeDesignation(ref));
289 }
290 return typeDesignations;
291 }
292
293 public NameTypeDesignation getNameTypeDesignation(TypedEntityReference baseEntityReference) {
294 Set<TypeDesignationBase> typeDesignations = getTypeDesignationsInWorkingSet(baseEntityReference);
295 if(typeDesignations.size() == 1){
296 TypeDesignationBase item = typeDesignations.iterator().next();
297 return (NameTypeDesignation)item ;
298 }
299 if(typeDesignations.size() == 0){
300 return null;
301 }
302 if(typeDesignations.size() > 1){
303 throw new RuntimeException("Workingsets of NameTypeDesignations must contain exactly one item.");
304 }
305 return null;
306 }
307
308 /**
309 * @param ref
310 * @return
311 */
312 private TypeDesignationBase findTypeDesignation(EntityReference ref) {
313 return typeDesignationManager != null ? typeDesignationManager.findTypeDesignation(ref) : null;
314 }
315
316 public Collection<TypeDesignationBase> typeDesignations() {
317 return typeDesignationManager != null ? typeDesignationManager.getTypeDesignations() : null;
318 }
319
320 /**
321 * @return the citationString
322 */
323 public String getNomenclaturalCitationString() {
324 if(citation == null){
325 return null;
326 }
327 if(INomenclaturalReference.class.isAssignableFrom(citation.getClass())){
328 return ((INomenclaturalReference)citation).getNomenclaturalCitation(citationDetail);
329 } else {
330 logger.error("The citation is not a NomenclaturalReference");
331 return citation.generateTitle();
332 }
333 }
334
335 /**
336 * @return the citationString
337 */
338 public String getBibliographicCitationString() {
339 if(citation == null){
340 return null;
341 } else {
342 if(StringUtils.isNotEmpty(citationDetail)){
343 // TODO see https://dev.e-taxonomy.eu/redmine/issues/6623
344 return citation.generateTitle().replaceAll("\\.$", "") + (StringUtils.isNotEmpty(citationDetail) ? ": " + citationDetail : "");
345 } else {
346 return citation.generateTitle();
347
348 }
349
350 }
351 }
352
353 public boolean isBlocked() {
354 return reg.getBlockedBy() != null && !reg.getBlockedBy().isEmpty();
355 }
356
357 /**
358 * @return the blockedBy
359 */
360 public Set<TypedEntityReference<Registration>> getBlockedBy() {
361
362 if(blockedBy == null){
363 blockedBy = new HashSet<>();
364 if(reg.getBlockedBy() != null){
365 for(Registration blockReg : reg.getBlockedBy()){
366 blockedBy.add(new TypedEntityReference<Registration>(Registration.class, blockReg.getUuid(), blockReg.getIdentifier()));
367 }
368 }
369 }
370 return blockedBy;
371 }
372
373 /**
374 * @return
375 */
376 public List<String> getValidationProblems() {
377 return validationProblems;
378 }
379
380 /**
381 * @return
382 */
383 public boolean isPersisted() {
384 return reg.isPersited();
385 }
386
387 }