merge from 2_4_Release branch
[jalview.git] / src / jalview / io / AlignFile.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.4)
3  * Copyright (C) 2008 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
4  * 
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  * 
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  * 
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
18  */
19 package jalview.io;
20
21 import java.io.*;
22 import java.util.*;
23
24 import jalview.datamodel.*;
25
26 /**
27  * DOCUMENT ME!
28  * 
29  * @author $author$
30  * @version $Revision$
31  */
32 public abstract class AlignFile extends FileParse
33 {
34   int noSeqs = 0;
35
36   int maxLength = 0;
37
38   /**
39    * Sequences to be added to form a new alignment.
40    */
41   protected Vector seqs;
42
43   /**
44    * annotation to be added to generated alignment object
45    */
46   protected Vector annotations;
47
48   /**
49    * Properties to be added to generated alignment object
50    */
51   protected Hashtable properties;
52
53   long start;
54
55   long end;
56
57   boolean jvSuffix = true;
58
59   /**
60    * Creates a new AlignFile object.
61    */
62   public AlignFile()
63   {
64   }
65
66   /**
67    * Constructor which parses the data from a file of some specified type.
68    * 
69    * @param inFile
70    *                Filename to read from.
71    * @param type
72    *                What type of file to read from (File, URL)
73    */
74   public AlignFile(String inFile, String type) throws IOException
75   {
76     super(inFile, type);
77
78     initData();
79
80     parse();
81   }
82
83   /**
84    * Attempt to read from the position where some other parsing process left
85    * off.
86    * 
87    * @param source
88    * @throws IOException
89    */
90   public AlignFile(FileParse source) throws IOException
91   {
92     super(source);
93     initData();
94     parse();
95   }
96
97   /**
98    * Return the seqs Vector
99    */
100   public Vector getSeqs()
101   {
102     return seqs;
103   }
104
105   /**
106    * Return the Sequences in the seqs Vector as an array of Sequences
107    */
108   public SequenceI[] getSeqsAsArray()
109   {
110     SequenceI[] s = new SequenceI[seqs.size()];
111
112     for (int i = 0; i < seqs.size(); i++)
113     {
114       s[i] = (SequenceI) seqs.elementAt(i);
115     }
116
117     return s;
118   }
119
120   /**
121    * called by AppletFormatAdapter to generate an annotated alignment, rather
122    * than bare sequences.
123    * 
124    * @param al
125    */
126   public void addAnnotations(Alignment al)
127   {
128     addProperties(al);
129     for (int i = 0; i < annotations.size(); i++)
130     {
131       al.addAnnotation((AlignmentAnnotation) annotations.elementAt(i));
132     }
133
134   }
135
136   /**
137    * Add any additional information extracted from the file to the alignment
138    * properties.
139    * 
140    * @note implicitly called by addAnnotations()
141    * @param al
142    */
143   public void addProperties(Alignment al)
144   {
145     if (properties != null && properties.size() > 0)
146     {
147       Enumeration keys = properties.keys();
148       Enumeration vals = properties.elements();
149       while (keys.hasMoreElements())
150       {
151         al.setProperty(keys.nextElement(), vals.nextElement());
152       }
153     }
154   }
155
156   /**
157    * Store a non-null key-value pair in a hashtable used to set alignment
158    * properties note: null keys will raise an error, null values will result in
159    * the key/value pair being silently ignored.
160    * 
161    * @param key -
162    *                non-null key object
163    * @param value -
164    *                non-null value
165    */
166   protected void setAlignmentProperty(Object key, Object value)
167   {
168     if (key == null)
169     {
170       throw new Error(
171               "Implementation error: Cannot have null alignment property key.");
172     }
173     if (value == null)
174     {
175       return; // null properties are ignored.
176     }
177     if (properties == null)
178     {
179       properties = new Hashtable();
180     }
181     properties.put(key, value);
182   }
183
184   protected Object getAlignmentProperty(Object key)
185   {
186     if (properties != null && key != null)
187     {
188       return properties.get(key);
189     }
190     return null;
191   }
192
193   /**
194    * Initialise objects to store sequence data in.
195    */
196   protected void initData()
197   {
198     seqs = new Vector();
199     annotations = new Vector();
200   }
201
202   /**
203    * DOCUMENT ME!
204    * 
205    * @param s
206    *                DOCUMENT ME!
207    */
208   protected void setSeqs(SequenceI[] s)
209   {
210     seqs = new Vector();
211
212     for (int i = 0; i < s.length; i++)
213     {
214       seqs.addElement(s[i]);
215     }
216   }
217
218   /**
219    * This method must be implemented to parse the contents of the file.
220    */
221   public abstract void parse() throws IOException;
222
223   /**
224    * Print out in alignment file format the Sequences in the seqs Vector.
225    */
226   public abstract String print();
227
228   public void addJVSuffix(boolean b)
229   {
230     jvSuffix = b;
231   }
232
233   /**
234    * A general parser for ids.
235    * 
236    * @String id Id to be parsed
237    */
238   Sequence parseId(String id)
239   {
240     Sequence seq = null;
241     id = id.trim();
242     int space = id.indexOf(" ");
243     if (space > -1)
244     {
245       seq = new Sequence(id.substring(0, space), "");
246       seq.setDescription(id.substring(space + 1));
247     }
248     else
249     {
250       seq = new Sequence(id, "");
251     }
252
253     return seq;
254   }
255
256   /**
257    * Creates the output id. Adds prefix Uniprot format source|id And suffix
258    * Jalview /start-end
259    * 
260    * @String id Id to be parsed
261    */
262   String printId(SequenceI seq)
263   {
264     return seq.getDisplayId(jvSuffix);
265   }
266
267   /**
268    * vector of String[] treeName, newickString pairs
269    */
270   Vector newickStrings = null;
271
272   protected void addNewickTree(String treeName, String newickString)
273   {
274     if (newickStrings == null)
275     {
276       newickStrings = new Vector();
277     }
278     newickStrings.addElement(new String[]
279     { treeName, newickString });
280   }
281
282   protected int getTreeCount()
283   {
284     if (newickStrings == null)
285     {
286       return 0;
287     }
288     return newickStrings.size();
289   }
290
291 }