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