solving compilation probelm due to class literal with type parameters
[cdm-vaadin.git] / src / main / java / eu / etaxonomy / cdm / vaadin / util / converter / TypeDesignationConverter.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.vaadin.util.converter;
10
11 import java.util.ArrayList;
12 import java.util.Collection;
13 import java.util.Collections;
14 import java.util.Comparator;
15 import java.util.HashMap;
16 import java.util.LinkedHashMap;
17 import java.util.LinkedList;
18 import java.util.List;
19 import java.util.Map;
20
21 import eu.etaxonomy.cdm.model.common.Language;
22 import eu.etaxonomy.cdm.model.name.NameTypeDesignation;
23 import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;
24 import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignationStatus;
25 import eu.etaxonomy.cdm.model.name.TaxonName;
26 import eu.etaxonomy.cdm.model.name.TypeDesignationBase;
27 import eu.etaxonomy.cdm.model.name.TypeDesignationStatusBase;
28 import eu.etaxonomy.cdm.vaadin.model.EntityReference;
29 import eu.etaxonomy.cdm.vaadin.view.registration.RegistrationValidationException;
30
31 /**
32 * Converts a collection of TypeDesignations, which should belong to the
33 * same name of course, into a string representation.
34 *
35 * Order of TypeDesignations in the resulting string:
36 * Type, Holotype, Lectotype, Epitypes
37 * @author a.kohlbecker
38 * @since Mar 10, 2017
39 *
40 */
41 public class TypeDesignationConverter {
42
43
44 private final String separator = ", ";
45
46 private Collection<TypeDesignationBase> typeDesignations;
47 private Map<TypeDesignationStatusBase<?>, Collection<EntityReference>> orderedStringsByType;
48 private LinkedHashMap<String, Collection<EntityReference>> orderedRepresentations = new LinkedHashMap<>();
49 private EntityReference typifiedName;
50
51 private String finalString = null;
52
53
54
55 /**
56 * @param taxonName
57 * @throws RegistrationValidationException
58 *
59 */
60 public TypeDesignationConverter(Collection<TypeDesignationBase> typeDesignations) throws RegistrationValidationException {
61 this.typeDesignations = typeDesignations;
62 orderedStringsByType = new HashMap<>();
63 typeDesignations.forEach(td -> putString(td.getTypeStatus(), new EntityReference(td.getId(), stringify(td))));
64 orderedRepresentations = buildOrderedRepresentations();
65 this.typifiedName = findTypifiedName();
66 }
67
68 private LinkedHashMap buildOrderedRepresentations(){
69
70 List<TypeDesignationStatusBase<?>> keyList = new LinkedList<>(orderedStringsByType.keySet());
71
72 Collections.sort(keyList, new Comparator<TypeDesignationStatusBase>() {
73 @Override
74 public int compare(TypeDesignationStatusBase o1, TypeDesignationStatusBase o2) {
75 // fix inverted order of cdm terms by -1*
76 return -1 * o1.compareTo(o2);
77 }
78 });
79
80 keyList.forEach(key -> orderedRepresentations.put(getTypeDesignationStytusLabel(key), orderedStringsByType.get(key)));
81 return orderedRepresentations;
82 }
83
84 public TypeDesignationConverter buildString(){
85
86 StringBuilder sb = new StringBuilder();
87
88 if(getTypifiedNameCache() != null){
89 sb.append(getTypifiedNameCache()).append(": ");
90 }
91
92 List<String> keyList = new LinkedList<>(orderedRepresentations.keySet());
93
94
95 keyList.forEach(key -> {
96 sb.append(key).append(": ");
97 orderedRepresentations.get(key).forEach(isAndString -> {
98 sb.append(isAndString.getLabel());
99 if(sb.length() > 0){
100 sb.append(separator);
101 }
102 });
103 });
104
105 finalString = sb.toString();
106 return this;
107 }
108
109 public Map<String, Collection<EntityReference>> getOrderedTypeDesignationRepresentations() {
110 return orderedRepresentations;
111 }
112
113 /**
114 * FIXME use the validation framework validators and to store the validation problems!!!
115 *
116 * @return
117 * @throws RegistrationValidationException
118 */
119 private EntityReference findTypifiedName() throws RegistrationValidationException {
120
121 List<String> problems = new ArrayList<>();
122
123 TaxonName typifiedName = null;
124
125 for(TypeDesignationBase<?> typeDesignation : typeDesignations){
126 typeDesignation.getTypifiedNames();
127 if(typeDesignation.getTypifiedNames().isEmpty()){
128
129 //TODO instead throw RegistrationValidationException()
130 problems.add("Missing typifiedName in " + typeDesignation.toString());
131 continue;
132 }
133 if(typeDesignation.getTypifiedNames().size() > 1){
134 //TODO instead throw RegistrationValidationException()
135 problems.add("Multiple typifiedName in " + typeDesignation.toString());
136 continue;
137 }
138 if(typifiedName == null){
139 // remember
140 typifiedName = typeDesignation.getTypifiedNames().iterator().next();
141 } else {
142 // compare
143 TaxonName otherTypifiedName = typeDesignation.getTypifiedNames().iterator().next();
144 if(typifiedName.getId() != otherTypifiedName.getId()){
145 //TODO instead throw RegistrationValidationException()
146 problems.add("Multiple typifiedName in " + typeDesignation.toString());
147 }
148 }
149
150 }
151 if(!problems.isEmpty()){
152 // FIXME use the validation framework
153 throw new RegistrationValidationException("Inconsistent type designations", problems);
154 }
155
156 if(typifiedName != null){
157 return new EntityReference(typifiedName.getId(), typifiedName.getTitleCache());
158 }
159 return null;
160 }
161
162
163 /**
164 * @return the title cache of the typifying name or <code>null</code>
165 */
166 public String getTypifiedNameCache() {
167 if(typifiedName != null){
168 return typifiedName.getLabel();
169 }
170 return null;
171 }
172
173 /**
174 * @return the title cache of the typifying name or <code>null</code>
175 */
176 public EntityReference getTypifiedName() {
177
178 return typifiedName;
179
180 }
181
182 /**
183 * @param key
184 * @return
185 */
186 protected String getTypeDesignationStytusLabel(TypeDesignationStatusBase<?> key) {
187 String typeLable;
188 if(key.equals( SpecimenTypeDesignationStatus.TYPE())){
189 typeLable = "Type";
190 } else {
191 typeLable = key.getPreferredRepresentation(Language.DEFAULT()).getLabel();
192 }
193 return typeLable;
194 }
195
196 /**
197 * @param td
198 * @return
199 */
200 private String stringify(TypeDesignationBase td) {
201
202 if(td instanceof NameTypeDesignation){
203 return stringify((NameTypeDesignation)td);
204 } else {
205 return stringify((SpecimenTypeDesignation)td);
206 }
207 }
208
209
210 /**
211 * @param td
212 * @return
213 */
214 protected String stringify(NameTypeDesignation td) {
215
216 StringBuffer sb = new StringBuffer();
217
218 if(td.getTypeName() != null){
219 sb.append(td.getTypeName().getTitleCache());
220 }
221 if(td.getCitation() != null){
222 sb.append(" ").append(td.getCitation().getTitleCache());
223 if(td.getCitationMicroReference() != null){
224 sb.append(":").append(td.getCitationMicroReference());
225 }
226 }
227 if(td.isNotDesignated()){
228 sb.append(" not designated");
229 }
230 if(td.isRejectedType()){
231 sb.append(" rejected");
232 }
233 if(td.isConservedType()){
234 sb.append(" conserved");
235 }
236 return sb.toString();
237 }
238
239 /**
240 * @param td
241 * @return
242 */
243 private String stringify(SpecimenTypeDesignation td) {
244 StringBuffer sb = new StringBuffer();
245
246 if(td.getTypeSpecimen() != null){
247 String nameTitleCache = td.getTypeSpecimen().getTitleCache();
248 if(getTypifiedNameCache() != null){
249 nameTitleCache = nameTitleCache.replace(getTypifiedNameCache(), "");
250 }
251 sb.append(nameTitleCache);
252 }
253
254 if(td.getCitation() != null){
255 sb.append(" ").append(td.getCitation().getTitleCache());
256 if(td.getCitationMicroReference() != null){
257 sb.append(" :").append(td.getCitationMicroReference());
258 }
259 }
260 if(td.isNotDesignated()){
261 sb.append(" not designated");
262 }
263
264 return sb.toString();
265 }
266
267 private void putString(TypeDesignationStatusBase<?> status, EntityReference idAndString){
268 // the cdm orderd term bases are ordered invers, fixing this for here
269 if(status == null){
270 status = SpecimenTypeDesignationStatus.TYPE();
271 }
272 if(!orderedStringsByType.containsKey(status)){
273 orderedStringsByType.put(status, new ArrayList<EntityReference>());
274 }
275 orderedStringsByType.get(status).add(idAndString);
276 }
277
278 public String print(){
279 return finalString;
280 }
281 }