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