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