1b6498f596e33e04c685b091acf2b71fac49315a
[jalview.git] / src / jalview / datamodel / SequenceFeature.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.datamodel;
22
23 import java.util.Hashtable;
24 import java.util.Vector;
25
26 /**
27  * DOCUMENT ME!
28  * 
29  * @author $author$
30  * @version $Revision$
31  */
32 public class SequenceFeature
33 {
34   public int begin;
35
36   public int end;
37
38   public float score;
39
40   public String type;
41
42   public String description;
43
44   public Hashtable otherDetails;
45
46   public Vector<String> links;
47
48   // Feature group can be set from a features file
49   // as a group of features between STARTGROUP and ENDGROUP markers
50   public String featureGroup;
51
52   public SequenceFeature()
53   {
54   }
55
56   /**
57    * Constructs a duplicate feature. Note: Uses clone on the otherDetails so
58    * only shallow copies are made of additional properties and method will
59    * silently fail if unclonable objects are found in the hash.
60    * 
61    * @param cpy
62    */
63   public SequenceFeature(SequenceFeature cpy)
64   {
65     if (cpy != null)
66     {
67       begin = cpy.begin;
68       end = cpy.end;
69       score = cpy.score;
70       if (cpy.type != null)
71       {
72         type = new String(cpy.type);
73       }
74       if (cpy.description != null)
75       {
76         description = new String(cpy.description);
77       }
78       if (cpy.featureGroup != null)
79       {
80         featureGroup = new String(cpy.featureGroup);
81       }
82       if (cpy.otherDetails != null)
83       {
84         try
85         {
86           otherDetails = (Hashtable) cpy.otherDetails.clone();
87         } catch (Exception e)
88         {
89           // Uncloneable objects in the otherDetails - don't complain
90         }
91       }
92       if (cpy.links != null && cpy.links.size() > 0)
93       {
94         links = new Vector<String>();
95         for (int i = 0, iSize = cpy.links.size(); i < iSize; i++)
96         {
97           links.addElement(cpy.links.elementAt(i));
98         }
99       }
100     }
101   }
102
103   public SequenceFeature(String type, String desc, String status,
104           int begin, int end, String featureGroup)
105   {
106     this.type = type;
107     this.description = desc;
108     setValue("status", status);
109     this.begin = begin;
110     this.end = end;
111     this.featureGroup = featureGroup;
112   }
113
114   public SequenceFeature(String type, String desc, int begin, int end,
115           float score, String featureGroup)
116   {
117     this.type = type;
118     this.description = desc;
119     this.begin = begin;
120     this.end = end;
121     this.score = score;
122     this.featureGroup = featureGroup;
123   }
124
125   public boolean equals(SequenceFeature sf)
126   {
127     if (begin != sf.begin || end != sf.end || score != sf.score)
128     {
129       return false;
130     }
131
132     if (!(type + description + featureGroup).equals(sf.type
133             + sf.description + sf.featureGroup))
134     {
135       return false;
136     }
137
138     return true;
139   }
140
141   /**
142    * DOCUMENT ME!
143    * 
144    * @return DOCUMENT ME!
145    */
146   public int getBegin()
147   {
148     return begin;
149   }
150
151   public void setBegin(int start)
152   {
153     this.begin = start;
154   }
155
156   /**
157    * DOCUMENT ME!
158    * 
159    * @return DOCUMENT ME!
160    */
161   public int getEnd()
162   {
163     return end;
164   }
165
166   public void setEnd(int end)
167   {
168     this.end = end;
169   }
170
171   /**
172    * DOCUMENT ME!
173    * 
174    * @return DOCUMENT ME!
175    */
176   public String getType()
177   {
178     return type;
179   }
180
181   public void setType(String type)
182   {
183     this.type = type;
184   }
185
186   /**
187    * DOCUMENT ME!
188    * 
189    * @return DOCUMENT ME!
190    */
191   public String getDescription()
192   {
193     return description;
194   }
195
196   public void setDescription(String desc)
197   {
198     description = desc;
199   }
200
201   public String getFeatureGroup()
202   {
203     return featureGroup;
204   }
205
206   public void setFeatureGroup(String featureGroup)
207   {
208     this.featureGroup = featureGroup;
209   }
210
211   public void addLink(String labelLink)
212   {
213     if (links == null)
214     {
215       links = new Vector<String>();
216     }
217
218     links.insertElementAt(labelLink, 0);
219   }
220
221   public float getScore()
222   {
223     return score;
224   }
225
226   public void setScore(float value)
227   {
228     score = value;
229   }
230
231   /**
232    * Used for getting values which are not in the basic set. eg STRAND, FRAME
233    * for GFF file
234    * 
235    * @param key
236    *          String
237    */
238   public Object getValue(String key)
239   {
240     if (otherDetails == null)
241     {
242       return null;
243     }
244     else
245     {
246       return otherDetails.get(key);
247     }
248   }
249
250   /**
251    * Used for setting values which are not in the basic set. eg STRAND, FRAME
252    * for GFF file
253    * 
254    * @param key
255    *          eg STRAND
256    * @param value
257    *          eg +
258    */
259   public void setValue(String key, Object value)
260   {
261     if (value != null)
262     {
263       if (otherDetails == null)
264       {
265         otherDetails = new Hashtable();
266       }
267
268       otherDetails.put(key, value);
269     }
270   }
271
272   /*
273    * The following methods are added to maintain the castor Uniprot mapping file
274    * for the moment.
275    */
276   public void setStatus(String status)
277   {
278     setValue("status", status);
279   }
280
281   public String getStatus()
282   {
283     if (otherDetails != null)
284     {
285       String stat = (String) otherDetails.get("status");
286       if (stat != null)
287       {
288         return new String(stat);
289       }
290     }
291     return null;
292   }
293
294   public void setPosition(int pos)
295   {
296     begin = pos;
297     end = pos;
298   }
299
300   public int getPosition()
301   {
302     return begin;
303   }
304
305   public int getStrand()
306   {
307     String str;
308     if (otherDetails == null
309             || (str = otherDetails.get("STRAND").toString()) == null)
310     {
311       return 0;
312     }
313     if (str.equals("-"))
314     {
315       return -1;
316     }
317     if (str.equals("+"))
318     {
319       return 1;
320     }
321     return 0;
322   }
323
324 }