2 * Jalview - A Sequence Alignment Editor and Viewer
3 * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
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.
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.
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
24 * implements a random access wrapper around a particular datasource, for passing to
25 * identifyFile and AlignFile objects.
27 public class FileParse
29 public File inFile=null;
30 protected char suffixSeparator = '#';
32 * '#' separated string tagged on to end of filename
33 * or url that was clipped off to resolve to valid filename
35 protected String suffix=null;
36 protected String type=null;
37 protected BufferedReader dataIn=null;
38 protected String errormessage="UNITIALISED SOURCE";
39 protected boolean error=true;
40 protected String warningMessage=null;
42 * size of readahead buffer used for when initial stream position is marked.
44 final int READAHEAD_LIMIT=2048;
49 * Attempt to open a file as a datasource.
50 * Sets error and errormessage if fileStr was invalid.
52 * @return this.error (true if the source was invalid)
54 private boolean checkFileSource(String fileStr) throws IOException {
56 this.inFile = new File(fileStr);
57 // check to see if it's a Jar file in disguise.
58 if (!inFile.exists()) {
59 errormessage = "FILE NOT FOUND";
62 if (!inFile.canRead()) {
63 errormessage = "FILE CANNOT BE OPENED FOR READING";
66 if (inFile.isDirectory()) {
67 // this is really a 'complex' filetype - but we don't handle directory reads yet.
68 errormessage = "FILE IS A DIRECTORY";
72 dataIn = new BufferedReader(new FileReader(fileStr));
76 private boolean checkURLSource(String fileStr) throws IOException, MalformedURLException
78 errormessage = "URL NOT FOUND";
79 URL url = new URL(fileStr);
80 dataIn = new BufferedReader(new InputStreamReader(url.openStream()));
84 * sets the suffix string (if any) and returns remainder (if suffix was detected)
86 * @return truncated fileStr or null
88 private String extractSuffix(String fileStr) {
89 // first check that there wasn't a suffix string tagged on.
90 int sfpos = fileStr.lastIndexOf(suffixSeparator);
91 if (sfpos>-1 && sfpos<fileStr.length()-1) {
92 suffix = fileStr.substring(sfpos+1);
93 // System.err.println("DEBUG: Found Suffix:"+suffix);
94 return fileStr.substring(0,sfpos);
99 * Create a datasource for input to Jalview.
100 * See AppletFormatAdapter for the types of sources that are handled.
101 * @param fileStr - datasource locator/content
102 * @param type - protocol of source
103 * @throws MalformedURLException
104 * @throws IOException
106 public FileParse(String fileStr, String type)
107 throws MalformedURLException, IOException
112 if (type.equals(AppletFormatAdapter.FILE))
114 if (checkFileSource(fileStr)) {
115 String suffixLess = extractSuffix(fileStr);
116 if (suffixLess!=null)
118 if (checkFileSource(suffixLess))
120 throw new IOException("Problem opening "+inFile+" (also tried "+suffixLess+") : "+errormessage);
124 throw new IOException("Problem opening "+inFile+" : "+errormessage);
128 else if (type.equals(AppletFormatAdapter.URL))
131 checkURLSource(fileStr);
132 if (suffixSeparator=='#')
133 extractSuffix(fileStr); // URL lref is stored for later reference.
134 } catch (IOException e) {
135 String suffixLess = extractSuffix(fileStr);
136 if (suffixLess==null)
141 checkURLSource(suffixLess);
143 catch (IOException e2) {
144 errormessage = "BAD URL WITH OR WITHOUT SUFFIX";
145 throw(e); // just pass back original - everything was wrong.
151 errormessage = "CANNOT ACCESS DATA AT URL '"+fileStr+"' ("+e.getMessage()+")";
155 else if (type.equals(AppletFormatAdapter.PASTE))
157 errormessage = "PASTE INACCESSIBLE!";
158 dataIn = new BufferedReader(new StringReader(fileStr));
160 else if (type.equals(AppletFormatAdapter.CLASSLOADER))
162 errormessage = "RESOURCE CANNOT BE LOCATED";
163 java.io.InputStream is = getClass().getResourceAsStream("/" + fileStr);
165 String suffixLess = extractSuffix(fileStr);
166 if (suffixLess!=null)
167 is = getClass().getResourceAsStream("/" + suffixLess);
171 dataIn = new BufferedReader(new java.io.InputStreamReader(is));
178 // pass up the reason why we have no source to read from
179 throw new IOException("Failed to read data from source:\n"+errormessage);
182 dataIn.mark(READAHEAD_LIMIT);
184 public String nextLine()
188 return dataIn.readLine();
189 throw new IOException("Invalid Source Stream:"+errormessage);
192 public boolean isValid()
197 * closes the datasource and tidies up.
198 * source will be left in an error state
200 public void close() throws IOException
202 errormessage="EXCEPTION ON CLOSE";
206 errormessage="SOURCE IS CLOSED";
209 * rewinds the datasource the beginning.
212 public void reset() throws IOException
214 if (dataIn!=null && !error) {
217 throw new IOException("Implementation Error: Reset called for invalid source.");
222 * @return true if there is a warning for the user
224 public boolean hasWarningMessage() {
225 return (warningMessage!=null && warningMessage.length()>0);
229 * @return empty string or warning message about file that was just parsed.
231 public String getWarningMessage() {
232 return warningMessage;