JAL-2994 put ‘\’ first in character class clause of regex - otherwise doesn’t compile...
[jalview.git] / src / jalview / io / FastaFile.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.io;
22
23 import jalview.datamodel.Alignment;
24 import jalview.datamodel.AlignmentAnnotation;
25 import jalview.datamodel.Annotation;
26 import jalview.datamodel.Sequence;
27 import jalview.datamodel.SequenceI;
28
29 import java.io.IOException;
30
31 /**
32  * DOCUMENT ME!
33  * 
34  * @author $author$
35  * @version $Revision$
36  */
37 public class FastaFile extends AlignFile
38 {
39   /**
40    * Length of a sequence line
41    */
42   int len = 72;
43
44   StringBuffer out;
45
46   /**
47    * Creates a new FastaFile object.
48    */
49   public FastaFile()
50   {
51   }
52
53   /**
54    * Creates a new FastaFile object.
55    * 
56    * @param inFile
57    *          DOCUMENT ME!
58    * @param sourceType
59    *          DOCUMENT ME!
60    * 
61    * @throws IOException
62    *           DOCUMENT ME!
63    */
64   public FastaFile(String inFile, DataSourceType sourceType)
65           throws IOException
66   {
67     super(inFile, sourceType);
68   }
69
70   public FastaFile(FileParse source) throws IOException
71   {
72     super(source);
73   }
74
75   public FastaFile(SequenceI[] seqs)
76   {
77     super(seqs);
78   }
79
80   /**
81    * DOCUMENT ME!
82    * 
83    * @throws IOException
84    *           DOCUMENT ME!
85    */
86   @Override
87   public void parse() throws IOException
88   {
89     StringBuffer sb = new StringBuffer();
90     boolean firstLine = true;
91
92     String line, uline;
93     Sequence seq = null;
94
95     boolean annotation = false;
96
97     while ((uline = nextLine()) != null)
98     {
99       line = uline.trim();
100       if (line.length() > 0)
101       {
102         if (line.charAt(0) == '>')
103         {
104           if (line.startsWith(">#_"))
105           {
106             if (annotation)
107             {
108               annotations.addElement(makeAnnotation(seq, sb));
109             }
110           }
111           else
112           {
113             annotation = false;
114           }
115
116           if (!firstLine)
117           {
118             seq.setSequence(sb.toString());
119
120             if (!annotation)
121             {
122               seqs.addElement(seq);
123             }
124           }
125
126           seq = parseId(line.substring(1));
127           firstLine = false;
128
129           sb = new StringBuffer();
130
131           if (line.startsWith(">#_"))
132           {
133             annotation = true;
134           }
135         }
136         else
137         {
138           sb.append(annotation ? uline : line);
139         }
140       }
141     }
142
143     if (annotation)
144     {
145       annotations.addElement(makeAnnotation(seq, sb));
146     }
147
148     else if (!firstLine)
149     {
150       seq.setSequence(sb.toString());
151       seqs.addElement(seq);
152     }
153   }
154
155   private AlignmentAnnotation makeAnnotation(SequenceI seq, StringBuffer sb)
156   {
157     Annotation[] anots = new Annotation[sb.length()];
158     char cb;
159     for (int i = 0; i < anots.length; i++)
160     {
161       char cn = sb.charAt(i);
162       if (cn != ' ')
163       {
164         anots[i] = new Annotation("" + cn, null, ' ', Float.NaN);
165       }
166     }
167     AlignmentAnnotation aa = new AlignmentAnnotation(
168             seq.getName().substring(2), seq.getDescription(), anots);
169     return aa;
170   }
171
172   /**
173    * called by AppletFormatAdapter to generate an annotated alignment, rather
174    * than bare sequences.
175    * 
176    * @param al
177    */
178   public void addAnnotations(Alignment al)
179   {
180     addProperties(al);
181     for (int i = 0; i < annotations.size(); i++)
182     {
183       AlignmentAnnotation aa = annotations.elementAt(i);
184       aa.setPadGaps(true, al.getGapCharacter());
185       al.addAnnotation(aa);
186     }
187   }
188
189   @Override
190   public String print(SequenceI[] s, boolean jvsuffix)
191   {
192     out = new StringBuffer();
193     int i = 0;
194
195     while ((i < s.length) && (s[i] != null))
196     {
197       out.append(">" + printId(s[i], jvsuffix));
198       if (s[i].getDescription() != null)
199       {
200         out.append(" " + s[i].getDescription());
201       }
202
203       out.append(newline);
204
205       int nochunks = (s[i].getLength() / len)
206               + (s[i].getLength() % len > 0 ? 1 : 0);
207
208       for (int j = 0; j < nochunks; j++)
209       {
210         int start = j * len;
211         int end = start + len;
212
213         if (end < s[i].getLength())
214         {
215           out.append(s[i].getSequenceAsString(start, end) + newline);
216         }
217         else if (start < s[i].getLength())
218         {
219           out.append(s[i].getSequenceAsString(start, s[i].getLength())
220                   + newline);
221         }
222       }
223
224       i++;
225     }
226
227     return out.toString();
228   }
229 }