Add support RNAML format
[jalview.git] / src / jalview / io / BLCFile.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
3  * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, 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 java.io.*;
21 import java.util.*;
22
23 import javax.xml.parsers.ParserConfigurationException;
24
25 import org.xml.sax.SAXException;
26
27 import fr.orsay.lri.varna.exceptions.ExceptionFileFormatOrSyntax;
28 import fr.orsay.lri.varna.exceptions.ExceptionLoadingFailed;
29 import fr.orsay.lri.varna.exceptions.ExceptionPermissionDenied;
30
31 import jalview.datamodel.*;
32
33 /**
34  * DOCUMENT ME!
35  * 
36  * @author $author$
37  * @version $Revision$
38  */
39 public class BLCFile extends AlignFile
40 {
41   Vector titles;
42
43   /**
44    * Creates a new BLCFile object.
45    */
46   public BLCFile()
47   {
48   }
49
50   /**
51    * Creates a new BLCFile object.
52    * 
53    * @param inFile
54    *          DOCUMENT ME!
55    * @param type
56    *          DOCUMENT ME!
57    * 
58    * @throws IOException
59    *           DOCUMENT ME!
60  * @throws SAXException 
61  * @throws ParserConfigurationException 
62  * @throws ExceptionFileFormatOrSyntax 
63  * @throws ExceptionLoadingFailed 
64  * @throws ExceptionPermissionDenied 
65    */
66   public BLCFile(String inFile, String type) throws IOException, ExceptionFileFormatOrSyntax, ParserConfigurationException, SAXException, ExceptionPermissionDenied, ExceptionLoadingFailed
67   {
68     super(inFile, type);
69   }
70
71   public BLCFile(FileParse source) throws IOException, ExceptionFileFormatOrSyntax, ParserConfigurationException, SAXException, ExceptionPermissionDenied, ExceptionLoadingFailed
72   {
73     super(source);
74   }
75
76   /**
77    * DOCUMENT ME!
78    */
79   public void initData()
80   {
81     super.initData();
82     titles = new Vector();
83   }
84
85   /**
86    * Control the number of block iterations to skip before returning. set to 0
87    * to read first block file entry only set to -1 to read last block file entry
88    * only set to greater than zero to skip at most that many entries before
89    * parsing
90    */
91   int iterationSkips = 0;
92
93   /**
94    * The iteration number for the alignment actually parsed from the blc file
95    */
96   int iterationCount = 0;
97
98   /**
99    * DOCUMENT ME!
100    */
101   public void parse() throws IOException
102   {
103     StringBuffer headerLines = new StringBuffer();
104     int numHeaderLines = 0; // number of lines appended.
105     StringBuffer[] seqstrings = null;
106     if (suffix != null)
107     {
108       try
109       {
110         iterationSkips = Integer.parseInt(suffix);
111       } catch (NumberFormatException e)
112       {
113         iterationSkips = 0; // first
114       }
115     }
116
117     String line = null;
118
119     do
120     {
121       boolean idsFound = false;
122       boolean newids = false;
123       // search for ID header.
124       do
125       {
126         line = nextLine();
127         if (line == null)
128           break;
129         // seek end of ids
130         if (line.indexOf("*") > -1)
131         {
132           idsFound = true;
133
134           break;
135         }
136
137         int abracket = line.indexOf(">");
138
139         if (abracket > -1)
140         {
141
142           if (iterationCount > 0 && !newids)
143           {
144             // we have a new set of IDs to record.
145             newids = true;
146             seqs.removeAllElements();
147           }
148
149           line = line.substring(abracket + 1);
150
151           Sequence seq = parseId(line);
152           seqs.addElement(seq);
153         }
154         else
155         {
156           // header lines - keep them for the alignment comments.
157           headerLines.append(line);
158           headerLines.append(newline);
159           numHeaderLines++;
160         }
161       } while (!idsFound);
162       if (line == null)
163         break; // end of file.
164       int starCol = line.indexOf("*");
165       seqstrings = new StringBuffer[seqs.size()];
166
167       for (int i = 0; i < seqs.size(); i++)
168       {
169         if (seqstrings[i] == null)
170         {
171           seqstrings[i] = new StringBuffer();
172         }
173       }
174
175       try
176       {
177         line = nextLine();
178         while (line != null && line.indexOf("*") == -1)
179         {
180           for (int i = 0; i < seqs.size(); i++)
181           {
182             if (line.length() > (i + starCol))
183             {
184               seqstrings[i].append(line.charAt(i + starCol));
185             }
186           }
187           line = nextLine();
188         }
189       } catch (IOException e)
190       {
191         if (iterationCount == 0)
192         {
193           throw (e); // otherwise we've just run out of iterations.
194         }
195         else
196         {
197           iterationSkips = 0;
198         }
199       }
200       iterationCount++;
201     } while (--iterationSkips != -1);
202
203     for (int i = 0; i < seqs.size(); i++)
204     {
205       Sequence newSeq = (Sequence) seqs.elementAt(i);
206
207       newSeq.setSequence(seqstrings[i].toString());
208     }
209     if (seqs.size() > 0)
210     {
211       if (headerLines.length() > 1 + numHeaderLines) // could see if buffer is
212         // just whitespace or not.
213         setAlignmentProperty("Comments", headerLines.toString());
214       setAlignmentProperty("iteration", "" + iterationCount);
215     }
216   }
217
218   /**
219    * DOCUMENT ME!
220    * 
221    * @return DOCUMENT ME!
222    */
223   public String print()
224   {
225     return print(getSeqsAsArray());
226   }
227
228   /**
229    * DOCUMENT ME!
230    * 
231    * @param s
232    *          DOCUMENT ME!
233    * 
234    * @return DOCUMENT ME!
235    */
236   public String print(SequenceI[] s)
237   {
238     StringBuffer out = new StringBuffer();
239     /**
240      * A general parser for ids. Will look for dbrefs in Uniprot format
241      * source|id And also Jalview /start-end
242      * 
243      * @String id Id to be parsed
244      */
245     int i = 0;
246     int max = -1;
247
248     while ((i < s.length) && (s[i] != null))
249     {
250       out.append(">" + printId(s[i]));
251       if (s[i].getDescription() != null)
252       {
253         out.append(" " + s[i].getDescription());
254       }
255
256       out.append(newline);
257
258       if (s[i].getSequence().length > max)
259       {
260         max = s[i].getSequence().length;
261       }
262
263       i++;
264     }
265
266     out.append("* iteration 1");
267     out.append(newline);
268
269     for (int j = 0; j < max; j++)
270     {
271       i = 0;
272
273       while ((i < s.length) && (s[i] != null))
274       {
275         if (s[i].getSequence().length > j)
276         {
277           out.append(s[i].getSequenceAsString(j, j + 1));
278         }
279         else
280         {
281           out.append("-");
282         }
283
284         i++;
285       }
286
287       out.append(newline);
288     }
289
290     out.append("*");
291     out.append(newline);
292
293     return out.toString();
294   }
295 }