JAL-3417 propagate description from AnnotationProvider to the worker
[jalview.git] / src / jalview / workers / AnnotationWorker.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.workers;
22
23 import jalview.api.AlignViewportI;
24 import jalview.api.AlignmentViewPanel;
25 import jalview.datamodel.AlignmentAnnotation;
26 import jalview.datamodel.AlignmentI;
27 import jalview.renderer.seqfeatures.FeatureRenderer;
28
29 import java.util.ArrayList;
30 import java.util.List;
31
32 /**
33  * A class to create and update one or more alignment annotations, given a
34  * 'calculator'. Intended to support a 'plug-in' annotation worker which
35  * implements the AnnotationProviderI interface.
36  */
37 class AnnotationWorker extends AlignCalcWorker
38 {
39   /*
40    * the provider of the annotation calculations
41    */
42   AnnotationProviderI counter;
43
44   /**
45    * Constructor
46    * 
47    * @param af
48    * @param counter
49    */
50   public AnnotationWorker(AlignViewportI viewport, AlignmentViewPanel panel,
51           AnnotationProviderI counter)
52   {
53     super(viewport, panel);
54     ourAnnots = new ArrayList<>();
55     this.counter = counter;
56     calcMan.registerWorker(this);
57   }
58
59   @Override
60   public void run()
61   {
62     try
63     {
64       calcMan.notifyStart(this);
65
66       while (!calcMan.notifyWorking(this))
67       {
68         try
69         {
70           Thread.sleep(200);
71         } catch (InterruptedException ex)
72         {
73           ex.printStackTrace();
74         }
75       }
76       if (alignViewport.isClosed())
77       {
78         abortAndDestroy();
79         return;
80       }
81
82       // removeAnnotation();
83       AlignmentI alignment = alignViewport.getAlignment();
84       if (alignment != null)
85       {
86         try
87         {
88           List<AlignmentAnnotation> anns = counter.calculateAnnotation(
89                   alignment, new FeatureRenderer(alignViewport));
90           for (AlignmentAnnotation ann : anns)
91           {
92             AlignmentAnnotation theAnn = alignment.findOrCreateAnnotation(
93                     ann.label, ann.getCalcId(), ann.autoCalculated,
94                     ann.sequenceRef,
95                     ann.groupRef);
96             if (ann.description!=null) {
97               theAnn.description = ann.description;
98             }
99             theAnn.showAllColLabels = true;
100             theAnn.graph = AlignmentAnnotation.BAR_GRAPH;
101             theAnn.scaleColLabel = true;
102             theAnn.annotations = ann.annotations;
103             setGraphMinMax(theAnn, theAnn.annotations);
104             theAnn.validateRangeAndDisplay();
105             if (!ourAnnots.contains(theAnn))
106             {
107               ourAnnots.add(theAnn);
108             }
109             // alignment.addAnnotation(ann);
110           }
111         } catch (IndexOutOfBoundsException x)
112         {
113           // probable race condition. just finish and return without any fuss.
114           return;
115         }
116       }
117     } catch (OutOfMemoryError error)
118     {
119       ap.raiseOOMWarning("calculating annotations", error);
120       calcMan.disableWorker(this);
121     } finally
122     {
123       calcMan.workerComplete(this);
124     }
125
126     if (ap != null)
127     {
128       ap.adjustAnnotationHeight();
129       // TODO: only need to update colour and geometry if panel height changes
130       // and view is coloured by annotation, and the annotation is actually
131       // changed!
132       ap.paintAlignment(true, true);
133     }
134   }
135
136   @Override
137   public void updateAnnotation()
138   {
139     // do nothing
140   }
141
142   /**
143    * Answers true to indicate that if this worker's annotation is deleted from
144    * the display, the worker should also be removed. This prevents it running
145    * and recreating the annotation when the alignment changes.
146    */
147   @Override
148   public boolean isDeletable()
149   {
150     return true;
151   }
152 }