ref #10186: remove conversation holder
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / view / search / derivative / DerivateLabelProvider.java
1 /**
2 * Copyright (C) 2013 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.taxeditor.view.search.derivative;
10
11 import java.util.ArrayList;
12 import java.util.Collection;
13 import java.util.HashMap;
14 import java.util.HashSet;
15 import java.util.List;
16 import java.util.Map;
17 import java.util.Map.Entry;
18 import java.util.Set;
19 import java.util.UUID;
20
21 import org.apache.commons.lang3.StringUtils;
22 import org.eclipse.jface.viewers.ColumnLabelProvider;
23 import org.eclipse.jface.viewers.TreeNode;
24 import org.eclipse.swt.graphics.Image;
25 import org.hibernate.LazyInitializationException;
26
27 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
28 import eu.etaxonomy.cdm.api.service.IOccurrenceService;
29 import eu.etaxonomy.cdm.api.service.molecular.ISequenceService;
30 import eu.etaxonomy.cdm.common.CdmUtils;
31 import eu.etaxonomy.cdm.format.CdmFormatterFactory;
32 import eu.etaxonomy.cdm.format.ICdmFormatter.FormatKey;
33 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
34 import eu.etaxonomy.cdm.model.common.CdmBase;
35 import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
36 import eu.etaxonomy.cdm.model.common.Identifier;
37 import eu.etaxonomy.cdm.model.molecular.DnaSample;
38 import eu.etaxonomy.cdm.model.molecular.Sequence;
39 import eu.etaxonomy.cdm.model.molecular.SingleRead;
40 import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;
41 import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
42 import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
43 import eu.etaxonomy.cdm.model.occurrence.GatheringEvent;
44 import eu.etaxonomy.cdm.model.occurrence.MediaSpecimen;
45 import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
46 import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationType;
47 import eu.etaxonomy.cdm.model.term.DefinedTerm;
48 import eu.etaxonomy.cdm.strategy.cache.common.IdentifiableEntityDefaultCacheStrategy;
49 import eu.etaxonomy.cdm.strategy.cache.occurrence.DnaSampleDefaultCacheStrategy;
50 import eu.etaxonomy.taxeditor.model.ImageResources;
51 import eu.etaxonomy.taxeditor.store.CdmStore;
52
53 /**
54 * Label provider for the views to show {@link SpecimenOrObservationBase}s.<br>
55 * <br>
56 * <b>Note:</b> If you use this label provider you need to assure that you
57 * created a {@link ConversationHolder} resp. have an open session because
58 * the labels are generated from various fields of the derivate hierarchy which
59 * are lazy loaded and could therefore throw a {@link LazyInitializationException}.<br>
60 * Use <b>{@link #setConversation(ConversationHolder)}</b> to assign the session to this provider.
61 */
62 public class DerivateLabelProvider extends ColumnLabelProvider {
63
64 private static final String NO_SAMPLE_DESIGNATION = "[no sample designation]";
65
66 private static Set<SingleRead> multiLinkSingleReads;
67
68 private static Map<DerivedUnit, Collection<SpecimenTypeDesignation>> typeDesignations;
69
70 // private ConversationHolder conversation;
71
72 private static DefinedTerm photoTerm = null;
73 private static DefinedTerm drawingTerm = null;
74 private static DefinedTerm specimenScanTerm = null;
75 private static DefinedTerm detailImageTerm = null;
76 private static DefinedTerm sampleDesignationTerm = null;
77
78 //FIXME: move static term getters to new singleton utility class
79 private static void initializeTerms() {
80 List<DefinedTerm> preferredTerms = CdmStore.getTermManager().getPreferredTerms(DefinedTerm.class);
81 for (DefinedTerm definedTerm : preferredTerms) {
82 if(definedTerm.getUuid().equals(UUID.fromString("c5c59c42-f254-471e-96c6-09f459f7c903"))){
83 photoTerm = definedTerm;
84 }
85 else if(definedTerm.getUuid().equals(UUID.fromString("669b0409-4aa4-4695-aae4-a95ed27bad4c"))){
86 drawingTerm = definedTerm;
87 }
88 else if(definedTerm.getUuid().equals(UUID.fromString("acda15be-c0e2-4ea8-8783-b9b0c4ad7f03"))){
89 specimenScanTerm = definedTerm;
90 }
91 else if(definedTerm.getUuid().equals(UUID.fromString("31eb8d02-bf5d-437c-bcc6-87a626445f34"))){
92 detailImageTerm = definedTerm;
93 }
94 else if(definedTerm.getUuid().equals(UUID.fromString("fadeba12-1be3-4bc7-9ff5-361b088d86fc"))){
95 sampleDesignationTerm = definedTerm;
96 }
97 }
98 }
99
100 public static DefinedTerm getLivingPlantPhotoTerm(){
101 if(photoTerm==null){
102 initializeTerms();
103 }
104 return photoTerm;
105 }
106
107 public static DefinedTerm getArtworkTerm(){
108 if(drawingTerm==null){
109 initializeTerms();
110 }
111 return drawingTerm;
112 }
113
114 public static DefinedTerm getSpecimenScanTerm(){
115 if(specimenScanTerm==null){
116 initializeTerms();
117 }
118 return specimenScanTerm;
119 }
120
121 public static DefinedTerm getDetailImageTerm(){
122 if(detailImageTerm==null){
123 initializeTerms();
124 }
125 return detailImageTerm;
126 }
127
128 public static DefinedTerm getSampleDesignationTerm(){
129 if(sampleDesignationTerm==null){
130 initializeTerms();
131 }
132 return sampleDesignationTerm;
133 }
134
135 @Override
136 public String getText(Object element) {
137 if(element instanceof TreeNode){
138 element = ((TreeNode) element).getValue();
139 }
140 String text = null;
141 if(element instanceof IdentifiableEntity
142 && ((IdentifiableEntity<?>) element).isProtectedTitleCache()){
143 return ((IdentifiableEntity<?>) element).getTitleCache();
144 }
145
146 //check if collection code does not exist -> use collection name then
147 FormatKey collectionKey = FormatKey.COLLECTION_CODE;
148 text = CdmFormatterFactory.format(element, new FormatKey[]{FormatKey.COLLECTION_CODE});
149 if(CdmUtils.isBlank(text)){
150 collectionKey = FormatKey.COLLECTION_NAME;
151 }
152
153 //Use titlecache for FieldUnits
154 if(element instanceof FieldUnit){
155 text = ((FieldUnit) element).getTitleCache();
156 }
157 else if(element instanceof MediaSpecimen){
158 MediaSpecimen mediaSpecimen = (MediaSpecimen)element;
159 text = mediaSpecimen.getTitleCache();
160 }
161 else if (element instanceof DnaSample) {
162 DnaSample dnaSample = (DnaSample)element;
163 if (!(dnaSample.cacheStrategy() instanceof DnaSampleDefaultCacheStrategy)){
164 dnaSample.setCacheStrategy(new DnaSampleDefaultCacheStrategy());
165 }
166 dnaSample.setTitleCache(null);
167 text = dnaSample.getTitleCache();
168 }
169 else if (element instanceof DerivedUnit) {
170 text = CdmFormatterFactory.format(element,
171 new FormatKey[] {
172 collectionKey, FormatKey.SPACE,
173 FormatKey.MOST_SIGNIFICANT_IDENTIFIER, FormatKey.SPACE
174 });
175 }
176 else if (element instanceof Sequence) {
177 text = CdmFormatterFactory.format(element,
178 new FormatKey[] {
179 FormatKey.SEQUENCE_DNA_MARKER, FormatKey.SPACE
180 });
181 }
182 else if (element instanceof SingleRead) {
183 text = CdmFormatterFactory.format(element,
184 new FormatKey[] {
185 FormatKey.SINGLE_READ_PHEROGRAM_TITLE_CACHE, FormatKey.SPACE,
186 FormatKey.AMPLIFICATION_LABEL, FormatKey.SPACE,
187 });
188 }
189 else if(element instanceof IdentifiableEntity){
190
191 IdentifiableEntity<?> identifiableEntity = (IdentifiableEntity<?>) element;
192 if(identifiableEntity.isProtectedTitleCache()){
193 text = identifiableEntity.getTitleCache();
194 }
195 }
196 if(CdmUtils.isBlank(text) || text.equals(IdentifiableEntityDefaultCacheStrategy.TITLE_CACHE_GENERATION_NOT_IMPLEMENTED)){
197 if(element instanceof CdmBase){
198 text = ((CdmBase) element).getUuid().toString();
199 }
200 else{
201 text = element.toString();
202 }
203 }
204 //remove dot at the end
205 if(text.endsWith(".")){
206 text = text.substring(0, text.length()-1);
207 }
208 return text;
209 }
210
211 @Override
212 public String getToolTipText(Object element) {
213 return getDerivateText(element);
214 }
215
216 //Note AM: not sure what this method is really used for, why do we need an explicit
217 // formatting for those few use-cases where this is used?
218 public static String getDerivateText(Object element){
219 //TODO: use list of strings to assemble labels to avoid adding the separator every time and to allow null values
220 TreeNode parentNode = null;
221 TreeNode node = null;
222 Object derivate = element;
223 if(element instanceof TreeNode){
224 node = (TreeNode) element;
225 parentNode = node.getParent();
226 //unwrap specimen from TreeNode
227 derivate = node.getValue();
228 }
229
230 final String emptyString = StringUtils.EMPTY;
231 final String separator = " ";
232
233 String label = emptyString;
234
235 //Field Unit
236 if(derivate instanceof FieldUnit){
237 FieldUnit fieldUnit = (FieldUnit)derivate;
238 if(fieldUnit.getGatheringEvent()!=null){
239 GatheringEvent gatheringEvent = fieldUnit.getGatheringEvent();
240 label += gatheringEvent.getCountry()!=null?gatheringEvent.getCountry().getLabel()+separator:emptyString;
241 label += gatheringEvent.getLocality()!=null?gatheringEvent.getLocality().getText()+separator:emptyString;
242 label += gatheringEvent.getGatheringDate()!=null?gatheringEvent.getGatheringDate()+separator:emptyString;
243 label += gatheringEvent.getCollector()!=null?gatheringEvent.getCollector()+separator:emptyString;
244 }
245 label += fieldUnit.getFieldNumber()!=null?fieldUnit.getFieldNumber():emptyString;
246 }
247 //MediaSpecimen
248 else if(derivate instanceof MediaSpecimen){
249 label = ((MediaSpecimen)derivate).generateTitle();
250 }
251 //TissueSample + DnaSample
252 else if(derivate instanceof DnaSample
253 && ((DnaSample) derivate).getRecordBasis()==SpecimenOrObservationType.DnaSample){
254 DnaSample dnaSample = (DnaSample)derivate;
255 //AM: maybe we can use cache strategy here, unclear why only sample designation is needed; unfortunately method documentation is missing
256 if(dnaSample.getRecordBasis()==SpecimenOrObservationType.DnaSample){
257 Identifier currentSampleDesignation = getCurrentSampleDesignation(dnaSample);
258 if(currentSampleDesignation!=null && currentSampleDesignation.getIdentifier()!=null){
259 label += currentSampleDesignation.getIdentifier()+separator;
260 }
261 else{
262 label += NO_SAMPLE_DESIGNATION+separator;
263 }
264 }
265 }
266 //DerivedUnit + TissueSample
267 else if(derivate instanceof DerivedUnit){
268 DerivedUnit derivedUnit = (DerivedUnit)derivate;
269 if(derivedUnit.getRecordBasis()==SpecimenOrObservationType.PreservedSpecimen){
270 //check for type designation
271 if(typeDesignations.get(derivedUnit)==null){
272 for (SpecimenTypeDesignation specimenTypeDesignation : derivedUnit.getSpecimenTypeDesignations()) {
273 addTypeDesignation(derivedUnit, specimenTypeDesignation);
274 }
275 }
276 //java.util.Collection<FieldUnit> fieldUnits = CdmStore.getService(IOccurrenceService.class).getFieldUnits(derivedUnit.getUuid());
277 //TODO : This is not generic anymore for performance reasons
278 Set<SpecimenOrObservationBase> originals = derivedUnit.getOriginals();
279 if(originals!=null && originals.size() ==1) {
280 SpecimenOrObservationBase<?> specimen = originals.iterator().next();
281 if(specimen instanceof FieldUnit) {
282 FieldUnit fieldUnit = (FieldUnit)specimen;
283 GatheringEvent gatheringEvent = fieldUnit.getGatheringEvent();
284 if(gatheringEvent!=null){
285 label += gatheringEvent.getCollector()!=null?gatheringEvent.getCollector()+separator:emptyString;
286 }
287 label += fieldUnit.getFieldNumber()!=null?fieldUnit.getFieldNumber()+separator:emptyString;
288 }
289 }
290
291 eu.etaxonomy.cdm.model.occurrence.Collection collection = derivedUnit.getCollection();
292 if(collection!=null){
293 label += collection.getCode()!=null?"("+collection.getCode()+")"+separator:emptyString;
294 }
295 String mostSignificantIdentifier = derivedUnit.getMostSignificantIdentifier();
296 label += mostSignificantIdentifier!=null?mostSignificantIdentifier+separator:emptyString;
297 }
298 else if(derivedUnit.getRecordBasis()==SpecimenOrObservationType.TissueSample){
299 if(derivedUnit.getKindOfUnit()!=null){
300 label += derivedUnit.getKindOfUnit()+separator;
301 }
302 Identifier currentSampleDesignation = getCurrentSampleDesignation(derivedUnit);
303 if(currentSampleDesignation!=null && currentSampleDesignation.getIdentifier()!=null){
304 label += currentSampleDesignation.getIdentifier() + separator;
305 }
306 else{
307 label += NO_SAMPLE_DESIGNATION + separator;
308 }
309 }
310 }
311 //Sequence
312 else if(derivate instanceof Sequence){
313 Sequence sequence = (Sequence)derivate;
314 Identifier currentSampleDesignation = getCurrentSampleDesignation(sequence);
315 if(currentSampleDesignation!=null && currentSampleDesignation.getIdentifier()!=null){
316 label += currentSampleDesignation.getIdentifier()+separator;
317 }
318 else{
319 label += NO_SAMPLE_DESIGNATION+separator;
320 }
321 label += sequence.getDnaMarker()!=null?sequence.getDnaMarker():emptyString;
322 }
323 //SingleRead
324 else if(derivate instanceof SingleRead){
325 SingleRead singleRead = (SingleRead)derivate;
326 if(parentNode!=null && parentNode.getValue() instanceof Sequence){
327 Sequence sequence = (Sequence) parentNode.getValue();
328 Identifier currentSampleDesignation = getCurrentSampleDesignation(sequence);
329 if(currentSampleDesignation!=null && currentSampleDesignation.getIdentifier()!=null){
330 label = currentSampleDesignation.getIdentifier()+separator;
331 }
332 else{
333 label += NO_SAMPLE_DESIGNATION+separator;
334 }
335 label += singleRead.getPrimer()!=null?singleRead.getPrimer().getLabel()+separator:emptyString;
336 if(sequence!=null && sequence.getDnaMarker()!=null){
337 label += sequence.getDnaMarker()+separator;
338 }
339 if(singleRead.getAmplificationResult()!=null && singleRead.getAmplificationResult().getAmplification()!=null){
340 label += singleRead.getAmplificationResult().getAmplification().getLabelCache()+separator;
341 }
342 }
343 }
344 //SOOB
345 else if(derivate instanceof SpecimenOrObservationBase){
346 SpecimenOrObservationBase<?> specimen = (SpecimenOrObservationBase<?>) derivate;
347 SpecimenOrObservationType type = specimen.getRecordBasis();
348 return specimen.getTitleCache() + (type!=null?" ["+type.toString()+"]":emptyString);
349 }
350 if(label.isEmpty()){
351 label = derivate.toString();
352 }
353 //remove last comma
354 else if(label.endsWith(separator)){
355 label = label.substring(0, label.length()-separator.length());
356 }
357 return label;
358 }
359
360 @Override
361 public Image getImage(Object element) {
362 if(element instanceof TreeNode){
363 element = ((TreeNode) element).getValue();
364 }
365 if(element instanceof CdmBase){
366 CdmBase cdmBase = (CdmBase)element;
367 boolean hasCharacterData = false;
368 if(cdmBase.isInstanceOf(SpecimenOrObservationBase.class)){
369 SpecimenOrObservationBase<?> specimen = HibernateProxyHelper.deproxy(cdmBase, SpecimenOrObservationBase.class);
370 if(specimen.hasCharacterData()){
371 hasCharacterData = true;
372 }
373 }
374 if(cdmBase.isInstanceOf(FieldUnit.class)){
375 return hasCharacterData?ImageResources.getImage(ImageResources.FIELD_UNIT_CHARACTER_DATA):ImageResources.getImage(ImageResources.FIELD_UNIT);
376 }
377 else if(cdmBase.isInstanceOf(DerivedUnit.class)){
378 DerivedUnit derivedUnit = HibernateProxyHelper.deproxy(element, DerivedUnit.class);
379
380 if(derivedUnit.getRecordBasis()==SpecimenOrObservationType.FieldUnit){
381 return hasCharacterData?ImageResources.getImage(ImageResources.FIELD_UNIT_CHARACTER_DATA):ImageResources.getImage(ImageResources.FIELD_UNIT);
382 }
383 else if(derivedUnit.getRecordBasis()==SpecimenOrObservationType.DnaSample){
384 return hasCharacterData?ImageResources.getImage(ImageResources.DNA_SAMPLE_DERIVATE_CHARACTER_DATA):ImageResources.getImage(ImageResources.DNA_SAMPLE_DERIVATE);
385 }
386 else if(derivedUnit.getRecordBasis()==SpecimenOrObservationType.TissueSample){
387 return hasCharacterData?ImageResources.getImage(ImageResources.TISSUE_SAMPLE_DERIVATE_CHARACTER_DATA):ImageResources.getImage(ImageResources.TISSUE_SAMPLE_DERIVATE);
388 }
389 else if(derivedUnit.getRecordBasis()==SpecimenOrObservationType.PreservedSpecimen){
390 if(typeDesignations.get(derivedUnit)!=null && !typeDesignations.get(derivedUnit).isEmpty()){
391 return ImageResources.getImage(ImageResources.SPECIMEN_DERIVATE_TYPE);
392 }
393 return hasCharacterData?ImageResources.getImage(ImageResources.SPECIMEN_DERIVATE_CHARACTER_DATA):ImageResources.getImage(ImageResources.SPECIMEN_DERIVATE);
394 }
395 else if(derivedUnit.getRecordBasis().isMedia()
396 || derivedUnit.getRecordBasis().isKindOf(SpecimenOrObservationType.Media)){
397 if(derivedUnit.getKindOfUnit()!=null){
398 if(derivedUnit.getKindOfUnit().equals(getArtworkTerm())){
399 return hasCharacterData?ImageResources.getImage(ImageResources.ARTWORK_DERIVATE_CHARACTER_DATA):ImageResources.getImage(ImageResources.ARTWORK_DERIVATE);
400 }
401 else if(derivedUnit.getKindOfUnit().equals(getLivingPlantPhotoTerm())){
402 return hasCharacterData?ImageResources.getImage(ImageResources.LIVING_PLANT_PHOTO_DERIVATE_CHARACTER_DATA):ImageResources.getImage(ImageResources.LIVING_PLANT_PHOTO_DERIVATE);
403 }
404 else if(derivedUnit.getKindOfUnit().equals(getSpecimenScanTerm())){
405 return hasCharacterData?ImageResources.getImage(ImageResources.SPECIMEN_SCAN_DERIVATE_CHARACTER_DATA):ImageResources.getImage(ImageResources.SPECIMEN_SCAN_DERIVATE);
406 }
407 else if(derivedUnit.getKindOfUnit().equals(getDetailImageTerm())){
408 return hasCharacterData?ImageResources.getImage(ImageResources.DETAIL_IMAGE_DERIVATE_CHARACTER_DATA):ImageResources.getImage(ImageResources.DETAIL_IMAGE_DERIVATE);
409 }
410 }
411 }
412 }
413 else if(cdmBase.isInstanceOf(Sequence.class)){
414 return ImageResources.getImage(ImageResources.SEQUENCE_DERIVATE);
415 }
416
417 else if(cdmBase.isInstanceOf(SingleRead.class)){
418 if(multiLinkSingleReads!=null && multiLinkSingleReads.contains(element)){
419 return ImageResources.getImage(ImageResources.SINGLE_READ_DERIVATE_MULTILINK);
420 }
421 else{
422 return ImageResources.getImage(ImageResources.SINGLE_READ_DERIVATE);
423 }
424 }
425 }
426 return ImageResources.getImage(ImageResources.DEFAULT_DERIVATIVE);
427 }
428
429 public static Identifier getCurrentSampleDesignation(CdmBase entity) {
430 if(entity.isInstanceOf(DnaSample.class)){
431 DnaSample dnaSample = HibernateProxyHelper.deproxy(entity, DnaSample.class);
432 return dnaSample.getIdentifier(DefinedTerm.uuidSampleDesignation);
433 }
434 else if(entity.isInstanceOf(Sequence.class)){
435 Sequence sequence = HibernateProxyHelper.deproxy(entity, Sequence.class);
436 if(sequence.getDnaSample()!=null){
437 return getCurrentSampleDesignation(sequence.getDnaSample());
438 }
439 }
440 return null;
441 }
442
443 private static void addTypeDesignation(DerivedUnit derivedUnit, SpecimenTypeDesignation typeDesignation){
444 Collection<SpecimenTypeDesignation> list = typeDesignations.get(derivedUnit);
445 if(list==null){
446 list = new ArrayList<>();
447 }
448 list.add(typeDesignation);
449 typeDesignations.put(derivedUnit, list);
450 }
451
452 public static Set<SingleRead> getMultiLinkSingleReads() {
453 return multiLinkSingleReads;
454 }
455
456 public void updateLabelCache(Collection<SpecimenOrObservationBase<?>> rootElements) {
457 multiLinkSingleReads = new HashSet<>();
458 typeDesignations = new HashMap<>();
459 for(Entry<SingleRead, Collection<Sequence>> entry:CdmStore.getService(ISequenceService.class).getSingleReadSequencesMap().entrySet()){
460 if(entry.getValue().size()>1){
461 multiLinkSingleReads.add(entry.getKey());
462 }
463 }
464 if(rootElements!=null){
465 Collection<DerivedUnit> derivedUnits = new ArrayList<>();
466 for (SpecimenOrObservationBase<?> specimenOrObservationBase : rootElements) {
467 List<DerivedUnit> childUnits = CdmStore.getService(IOccurrenceService.class).getAllChildDerivatives(specimenOrObservationBase.getUuid());
468 if (childUnits != null){
469 derivedUnits.addAll(childUnits);
470 }
471 if(specimenOrObservationBase.isInstanceOf(DerivedUnit.class)){
472 specimenOrObservationBase = CdmStore.getService(IOccurrenceService.class).load(specimenOrObservationBase.getUuid());
473 if (specimenOrObservationBase != null){
474 derivedUnits.add(HibernateProxyHelper.deproxy(specimenOrObservationBase, DerivedUnit.class));
475 }
476 }
477 }
478 for (DerivedUnit derivedUnit : derivedUnits) {
479 if(!derivedUnit.getSpecimenTypeDesignations().isEmpty()){
480 typeDesignations.put(derivedUnit, derivedUnit.getSpecimenTypeDesignations());
481 }
482 }
483 }
484 }
485
486 }