JAL-2738 update spike branch with latest
[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.description, false, null, null);
94             theAnn.showAllColLabels = true;
95             theAnn.graph = AlignmentAnnotation.BAR_GRAPH;
96             theAnn.scaleColLabel = true;
97             theAnn.annotations = ann.annotations;
98             setGraphMinMax(theAnn, theAnn.annotations);
99             theAnn.validateRangeAndDisplay();
100             if (!ourAnnots.contains(theAnn))
101             {
102               ourAnnots.add(theAnn);
103             }
104             // alignment.addAnnotation(ann);
105           }
106         } catch (IndexOutOfBoundsException x)
107         {
108           // probable race condition. just finish and return without any fuss.
109           return;
110         }
111       }
112     } catch (OutOfMemoryError error)
113     {
114       ap.raiseOOMWarning("calculating annotations", error);
115       calcMan.disableWorker(this);
116     } finally
117     {
118       calcMan.workerComplete(this);
119     }
120
121     if (ap != null)
122     {
123       ap.adjustAnnotationHeight();
124       // TODO: only need to update colour and geometry if panel height changes
125       // and view is coloured by annotation, and the annotation is actually
126       // changed!
127       ap.paintAlignment(true, true);
128     }
129   }
130
131   @Override
132   public void updateAnnotation()
133   {
134     // do nothing
135   }
136
137   /**
138    * Answers true to indicate that if this worker's annotation is deleted from
139    * the display, the worker should also be removed. This prevents it running
140    * and recreating the annotation when the alignment changes.
141    */
142   @Override
143   public boolean isDeletable()
144   {
145     return true;
146   }
147 }