Merge branch 'develop' into spike/JAL-4047/JAL-4048_columns_in_sequenceID
[jalview.git] / src / jalview / viewmodel / seqfeatures / IdColumns.java
1 package jalview.viewmodel.seqfeatures;
2
3 import java.awt.Color;
4 import java.util.ArrayList;
5 import java.util.LinkedHashMap;
6 import java.util.List;
7 import java.util.Vector;
8
9 import jalview.api.DBRefEntryI;
10 import jalview.datamodel.AlignmentI;
11 import jalview.datamodel.DBRefEntry;
12 import jalview.datamodel.SequenceFeature;
13 import jalview.datamodel.SequenceI;
14 import jalview.datamodel.features.SequenceFeaturesI;
15
16 public class IdColumns
17 {
18
19   AlignmentI alignment = null;
20
21   public IdColumns(AlignmentI al)
22   {
23     alignment = al;
24     columns.put(STRUCTURES_NUM.getLabel(), STRUCTURES_NUM);
25     updateTypeList();
26   }
27
28   public final static IdColumn STRUCTURES_NUM;
29   static
30   {
31     STRUCTURES_NUM = new IdColumn("3D Structures",
32             "Number of associated structure files", false);
33   }
34
35   LinkedHashMap<String, IdColumn> columns = new LinkedHashMap<String, IdColumn>();
36
37   /**
38    * register a feature on the columnset
39    * 
40    * @param sf
41    * @return true if feature was not seen before
42    */
43   boolean updateListForFeature(SequenceFeature sf)
44   {
45     String colname = sf.getType();
46     if (columns.get(colname) != null)
47     {
48       return false;
49     }
50
51     IdColumn col = new IdColumn(colname,
52             "Nonpositional feature: " + colname, false);
53     col.featureTypeName = sf.getType();
54     // col.featureGroupName = sf.getFeatureGroup();
55     columns.put(colname, col);
56     return true;
57   }
58
59   boolean updateListForDbxref(DBRefEntryI dbref)
60   {
61     String colname = dbref.getSource();
62     if (columns.get(colname) != null)
63     {
64       return false;
65     }
66
67     IdColumn col = new IdColumn(colname,
68             "Database CrossReference: " + colname, false);
69     col.DbRefName = colname;
70     // col.featureGroupName = sf.getFeatureGroup();
71     columns.put(colname, col);
72     return true;
73   }
74
75   public void updateTypeList()
76   {
77     for (SequenceI sq : alignment.getSequences())
78     {
79       SequenceI seq = sq;
80       while (seq.getDatasetSequence() != null)
81       {
82         seq = seq.getDatasetSequence();
83       }
84
85       SequenceFeaturesI sqf = seq.getFeatures();
86       List<SequenceFeature> nonpos = sqf.getNonPositionalFeatures();
87       if (nonpos != null)
88       {
89         for (SequenceFeature sf : nonpos)
90         {
91           updateListForFeature(sf);
92         }
93       }
94       if (seq.getDBRefs() != null)
95       {
96         for (DBRefEntryI dbr : seq.getDBRefs())
97         {
98           updateListForDbxref(dbr);
99         }
100       }
101     }
102   }
103
104   public void toggleVisible(String column)
105   {
106     IdColumn col = columns.get(column);
107     if (col != null)
108     {
109       col.visible = !col.visible;
110     }
111   }
112
113   public List<IdColumn> getVisible()
114   {
115     // probably want to cache this
116     ArrayList<IdColumn> vis = new ArrayList();
117     for (IdColumn col : columns.values())
118     {
119       if (col.visible)
120       {
121         vis.add(col);
122       }
123     }
124     return vis;
125   }
126
127   public final class ColumnCell
128   {
129     public final String label;
130
131     public final Color bg;
132
133     public final Color fg;
134
135     public ColumnCell(final String label, final Color bg, final Color fg)
136     {
137       this.label = label;
138       this.bg = bg;
139       this.fg = fg;
140     }
141   }
142
143   /**
144    * render the column value for this sequence
145    * 
146    * @param seq
147    * @param col
148    * @return
149    */
150   public ColumnCell getCellFor(SequenceI seq, IdColumn col)
151   {
152     ColumnCell cell = null;
153     if (col != null)
154     {
155       SequenceI dseq = seq;
156       while (dseq.getDatasetSequence() != null)
157       {
158         dseq = dseq.getDatasetSequence();
159       }
160       if (col == STRUCTURES_NUM)
161       {
162         Vector pdbE = dseq.getAllPDBEntries();
163         if (pdbE == null)
164         {
165           return null;
166         }
167         return new ColumnCell("" + pdbE.size(), Color.red, Color.white);
168       }
169       if (col.featureTypeName != null)
170       {
171         List<SequenceFeature> np = dseq.getFeatures()
172                 .getNonPositionalFeatures(col.featureTypeName);
173         if (np != null)
174         {
175           for (SequenceFeature npfeat : np)
176           {
177             // nb deal with multiplicities!
178             if (col.featureGroupName == null || (npfeat.featureGroup != null
179                     && npfeat.featureGroup.equals(col.featureGroupName)))
180             {
181               Color fg = Color.black;
182               Color bg = Color.white;
183
184               return new ColumnCell(npfeat.description, fg, bg);
185             }
186           }
187         }
188       }
189       if (col.DbRefName != null)
190       {
191         List<DBRefEntryI> refs = new ArrayList<DBRefEntryI>();
192         for (DBRefEntryI dbr : dseq.getDBRefs())
193         {
194           if (dbr.getSource().equals(col.DbRefName))
195           {
196             refs.add(dbr);
197           }
198         }
199         if (refs.size()==0)
200         {
201           return null;
202         }
203         StringBuilder dbr = new StringBuilder();
204         dbr.append(refs.size());
205         for (DBRefEntryI ref : refs)
206         {
207           dbr.append(" "+ref.getAccessionId());
208         }
209         return new ColumnCell(dbr.toString(), Color.black, Color.white);
210
211       }
212     }
213     // no value for this sequence in given column
214     return null;
215   }
216
217   public IdColumn[] getIdColumns()
218   {
219     return columns.values().toArray(new IdColumn[0]);
220   }
221 }