proxy commit for Anne Menard <menard.annec@gmail.com> throw generic exceptions (just...
[jalview.git] / src / jalview / io / AlignFile.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8)
3  * Copyright (C) 2012 J Procter, AM Waterhouse, LM Lui, J Engelhardt, G Barton, M Clamp, S Searle
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 of the License, or (at your option) any later version.
10  *  
11  * Jalview is distributed in the hope that it will be useful, but 
12  * WITHOUT ANY WARRANTY; without even the implied warranty 
13  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
14  * PURPOSE.  See the GNU General Public License for more details.
15  * 
16  * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 package jalview.io;
19
20 import jalview.datamodel.Alignment;
21 import jalview.datamodel.AlignmentAnnotation;
22 import jalview.datamodel.Sequence;
23 import jalview.datamodel.SequenceI;
24
25 import java.io.IOException;
26 import java.util.Enumeration;
27 import java.util.Hashtable;
28 import java.util.Vector;
29
30 import javax.xml.parsers.ParserConfigurationException;
31
32 import org.xml.sax.SAXException;
33
34 import fr.orsay.lri.varna.exceptions.ExceptionFileFormatOrSyntax;
35 import fr.orsay.lri.varna.exceptions.ExceptionLoadingFailed;
36 import fr.orsay.lri.varna.exceptions.ExceptionPermissionDenied;
37 import fr.orsay.lri.varna.exceptions.ExceptionUnmatchedClosingParentheses;
38
39 /**
40  * DOCUMENT ME!
41  * 
42  * @author $author$
43  * @version $Revision$
44  */
45 public abstract class AlignFile extends FileParse
46 {
47   int noSeqs = 0;
48
49   int maxLength = 0;
50
51   /**
52    * Sequences to be added to form a new alignment.
53    */
54   protected Vector<SequenceI> seqs;
55
56   /**
57    * annotation to be added to generated alignment object
58    */
59   protected Vector annotations;
60
61   /**
62    * Properties to be added to generated alignment object
63    */
64   protected Hashtable properties;
65
66   long start;
67
68   long end;
69
70   boolean jvSuffix = true;
71
72   /**
73    * Creates a new AlignFile object.
74    */
75   public AlignFile()
76   {
77           // Shouldn't we init data structures (JBPNote: not sure - initData is for initialising the structures used for reading from a datasource, and the bare constructor hasn't got any datasource)
78           initData();
79   }
80
81   /**
82    * Constructor which parses the data from a file of some specified type.
83    * 
84    * @param inFile
85    *          Filename to read from.
86    * @param type
87    *          What type of file to read from (File, URL)
88  * @throws Exception 
89    */
90   public AlignFile(String inFile, String type) throws Exception
91   {
92     super(inFile, type);
93     initData();
94     parse();
95     // sets the index of each sequence in the alignment
96     for (int i = 0, c = seqs.size(); i < c; i++)
97     {
98       seqs.get(i).setIndex(i);
99     }
100   }
101
102   /**
103    * Attempt to read from the position where some other parsing process left
104    * off.
105    * 
106    * @param source
107  * @throws Exception 
108    */
109   public AlignFile(FileParse source) throws Exception
110   {
111     super(source);
112     initData();
113     parse();
114     // sets the index of each sequence in the alignment
115     for (int i = 0, c = seqs.size(); i < c; i++)
116     {
117       seqs.get(i).setIndex(i);
118     }
119   }
120
121   /**
122    * Return the seqs Vector
123    */
124   public Vector<SequenceI> getSeqs()
125   {
126     return seqs;
127   }
128
129   /**
130    * Return the Sequences in the seqs Vector as an array of Sequences
131    */
132   public SequenceI[] getSeqsAsArray()
133   {
134     SequenceI[] s = new SequenceI[seqs.size()];
135
136     for (int i = 0; i < seqs.size(); i++)
137     {
138       s[i] = (SequenceI) seqs.elementAt(i);
139     }
140
141     return s;
142   }
143
144   /**
145    * called by AppletFormatAdapter to generate an annotated alignment, rather
146    * than bare sequences.
147    * 
148    * @param al
149    */
150   public void addAnnotations(Alignment al)
151   {
152     addProperties(al);
153     for (int i = 0; i < annotations.size(); i++)
154     {
155       // detect if annotations.elementAt(i) rna secondary structure
156       // if so then do:
157       /*
158        * SequenceFeature[] pairArray =
159        * Rna.GetBasePairsFromAlignmentAnnotation(annotations.elementAt(i));
160        * Rna.HelixMap(pairArray);
161        */
162       AlignmentAnnotation an = (AlignmentAnnotation) annotations
163               .elementAt(i);
164       an.validateRangeAndDisplay();
165       al.addAnnotation(an);
166     }
167
168   }
169
170   /**
171    * Add any additional information extracted from the file to the alignment
172    * properties.
173    * 
174    * @note implicitly called by addAnnotations()
175    * @param al
176    */
177   public void addProperties(Alignment al)
178   {
179     if (properties != null && properties.size() > 0)
180     {
181       Enumeration keys = properties.keys();
182       Enumeration vals = properties.elements();
183       while (keys.hasMoreElements())
184       {
185         al.setProperty(keys.nextElement(), vals.nextElement());
186       }
187     }
188   }
189
190   /**
191    * Store a non-null key-value pair in a hashtable used to set alignment
192    * properties note: null keys will raise an error, null values will result in
193    * the key/value pair being silently ignored.
194    * 
195    * @param key
196    *          - non-null key object
197    * @param value
198    *          - non-null value
199    */
200   protected void setAlignmentProperty(Object key, Object value)
201   {
202     if (key == null)
203     {
204       throw new Error(
205               "Implementation error: Cannot have null alignment property key.");
206     }
207     if (value == null)
208     {
209       return; // null properties are ignored.
210     }
211     if (properties == null)
212     {
213       properties = new Hashtable();
214     }
215     properties.put(key, value);
216   }
217
218   protected Object getAlignmentProperty(Object key)
219   {
220     if (properties != null && key != null)
221     {
222       return properties.get(key);
223     }
224     return null;
225   }
226
227   /**
228    * Initialise objects to store sequence data in.
229    */
230   protected void initData()
231   {
232     seqs = new Vector();
233     annotations = new Vector();
234   }
235
236   /**
237    * DOCUMENT ME!
238    * 
239    * @param s
240    *          DOCUMENT ME!
241    */
242   protected void setSeqs(SequenceI[] s)
243   {
244     seqs = new Vector();
245
246     for (int i = 0; i < s.length; i++)
247     {
248       seqs.addElement(s[i]);
249     }
250   }
251
252   /**
253    * This method must be implemented to parse the contents of the file.
254
255    */
256   public abstract void parse() throws Exception;
257
258   /**
259    * Print out in alignment file format the Sequences in the seqs Vector.
260    */
261   public abstract String print();
262
263   public void addJVSuffix(boolean b)
264   {
265     jvSuffix = b;
266   }
267
268   /**
269    * A general parser for ids.
270    * 
271    * @String id Id to be parsed
272    */
273   Sequence parseId(String id)
274   {
275     Sequence seq = null;
276     id = id.trim();
277     int space = id.indexOf(" ");
278     if (space > -1)
279     {
280       seq = new Sequence(id.substring(0, space), "");
281       seq.setDescription(id.substring(space + 1));
282     }
283     else
284     {
285       seq = new Sequence(id, "");
286     }
287
288     return seq;
289   }
290
291   /**
292    * Creates the output id. Adds prefix Uniprot format source|id And suffix
293    * Jalview /start-end
294    * 
295    * @String id Id to be parsed
296    */
297   String printId(SequenceI seq)
298   {
299     return seq.getDisplayId(jvSuffix);
300   }
301
302   /**
303    * vector of String[] treeName, newickString pairs
304    */
305   Vector newickStrings = null;
306
307   protected void addNewickTree(String treeName, String newickString)
308   {
309     if (newickStrings == null)
310     {
311       newickStrings = new Vector();
312     }
313     newickStrings.addElement(new String[]
314     { treeName, newickString });
315   }
316
317   protected int getTreeCount()
318   {
319     if (newickStrings == null)
320     {
321       return 0;
322     }
323     return newickStrings.size();
324   }
325
326 }