Clover icon

Coverage Report

  1. Project Clover database Wed Dec 3 2025 15:58:31 GMT
  2. Package jalview.io

File FileParse.java

 

Coverage histogram

../../img/srcFileCovDistChart6.png
37% of files have more coverage

Code metrics

94
233
34
1
864
577
101
0.43
6.85
34
2.97

Classes

Class Line # Actions
FileParse 56 233 101
0.5789473757.9%
 

Contributing tests

This file is covered by 336 tests. .

Source view

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 java.io.BufferedInputStream;
24    import java.io.BufferedReader;
25    import java.io.ByteArrayInputStream;
26    import java.io.File;
27    import java.io.FileInputStream;
28    import java.io.FileNotFoundException;
29    import java.io.FileReader;
30    import java.io.IOException;
31    import java.io.InputStream;
32    import java.io.InputStreamReader;
33    import java.io.Reader;
34    import java.io.StringReader;
35    import java.net.HttpURLConnection;
36    import java.net.MalformedURLException;
37    import java.net.SocketTimeoutException;
38    import java.net.URL;
39    import java.net.URLConnection;
40    import java.net.UnknownHostException;
41    import java.util.zip.GZIPInputStream;
42   
43    import jalview.api.AlignExportSettingsI;
44    import jalview.api.AlignViewportI;
45    import jalview.api.AlignmentViewPanel;
46    import jalview.api.FeatureSettingsModelI;
47    import jalview.bin.Console;
48    import jalview.util.HttpUtils;
49    import jalview.util.MessageManager;
50    import jalview.util.Platform;
51   
52    /**
53    * implements a random access wrapper around a particular datasource, for
54    * passing to identifyFile and AlignFile objects.
55    */
 
56    public class FileParse
57    {
58    protected static final String SPACE = " ";
59   
60    protected static final String TAB = "\t";
61   
62    /**
63    * text specifying source of data. usually filename or url.
64    */
65    private String dataName = "unknown source";
66   
67    public File inFile = null;
68   
69    private byte[] bytes; // from JavaScript
70   
 
71  0 toggle public byte[] getBytes()
72    {
73  0 return bytes;
74    }
75   
76    /**
77    * a viewport associated with the current file operation. May be null. May
78    * move to different object.
79    */
80    private AlignViewportI viewport;
81   
82    /**
83    * specific settings for exporting data from the current context
84    */
85    private AlignExportSettingsI exportSettings;
86   
87    /**
88    * sequence counter for FileParse object created from same data source
89    */
90    public int index = 1;
91   
92    /**
93    * separator for extracting specific 'frame' of a datasource for formats that
94    * support multiple records (e.g. BLC, Stockholm, etc)
95    */
96    protected char suffixSeparator = '#';
97   
98    /**
99    * character used to write newlines
100    */
101    protected String newline = System.getProperty("line.separator");
102   
 
103  177 toggle public void setNewlineString(String nl)
104    {
105  177 newline = nl;
106    }
107   
 
108  0 toggle public String getNewlineString()
109    {
110  0 return newline;
111    }
112   
113    /**
114    * '#' separated string tagged on to end of filename or url that was clipped
115    * off to resolve to valid filename
116    */
117    protected String suffix = null;
118   
119    protected DataSourceType dataSourceType = null;
120   
121    protected BufferedReader dataIn = null;
122   
123    protected String errormessage = "UNINITIALISED SOURCE";
124   
125    protected boolean error = true;
126   
127    protected String warningMessage = null;
128   
129    /**
130    * size of readahead buffer used for when initial stream position is marked.
131    */
132    final int READAHEAD_LIMIT = 2048;
133   
 
134  274 toggle public FileParse()
135    {
136    }
137   
138    /**
139    * Create a new FileParse instance reading from the same datasource starting
140    * at the current position. WARNING! Subsequent reads from either object will
141    * affect the read position of the other, but not the error state.
142    *
143    * @param from
144    */
 
145  910 toggle public FileParse(FileParse from) throws IOException
146    {
147  910 if (from == null)
148    {
149  0 throw new Error(MessageManager
150    .getString("error.implementation_error_null_fileparse"));
151    }
152  910 if (from == this)
153    {
154  0 return;
155    }
156  910 index = ++from.index;
157  910 inFile = from.inFile;
158  910 suffixSeparator = from.suffixSeparator;
159  910 suffix = from.suffix;
160  909 errormessage = from.errormessage; // inherit potential error messages
161  910 error = false; // reset any error condition.
162  909 dataSourceType = from.dataSourceType;
163  909 dataIn = from.dataIn;
164  910 if (dataIn != null)
165    {
166  910 mark();
167    }
168  910 dataName = from.dataName;
169    }
170   
171    /**
172    * Attempt to open a file as a datasource. Sets error and errormessage if
173    * fileStr was invalid.
174    *
175    * @param fileStr
176    * @return this.error (true if the source was invalid)
177    */
 
178  973 toggle private boolean checkFileSource(String fileStr) throws IOException
179    {
180  973 error = false;
181  973 this.inFile = new File(fileStr);
182    // check to see if it's a Jar file in disguise.
183  973 if (!inFile.exists())
184    {
185  0 errormessage = "FILE NOT FOUND";
186  0 error = true;
187    }
188  973 if (!inFile.canRead())
189    {
190  0 errormessage = "FILE CANNOT BE OPENED FOR READING";
191  0 error = true;
192    }
193  973 if (inFile.isDirectory())
194    {
195    // this is really a 'complex' filetype - but we don't handle directory
196    // reads yet.
197  0 errormessage = "FILE IS A DIRECTORY";
198  0 error = true;
199    }
200  973 if (!error)
201    {
202  973 try
203    {
204  973 dataIn = checkForGzipStream(new FileInputStream(fileStr));
205  973 dataName = fileStr;
206    } catch (Exception x)
207    {
208  0 warningMessage = "Failed to resolve " + fileStr
209    + " as a data source. (" + x.getMessage() + ")";
210    // x.printStackTrace();
211  0 error = true;
212    }
213  973 ;
214    }
215  973 return error;
216    }
217   
218    /**
219    * Recognise the 2-byte magic header for gzip streams
220    *
221    * https://recalll.co/ask/v/topic/java-How-to-check-if-InputStream-is-Gzipped/555aadd62bd27354438b90f6
222    *
223    * @param bytes
224    * - at least two bytes
225    * @return
226    * @throws IOException
227    */
 
228  978 toggle public static boolean isGzipStream(InputStream input) throws IOException
229    {
230  978 if (!input.markSupported())
231    {
232  1 Console.error(
233    "FileParse.izGzipStream: input stream must support mark/reset");
234  1 return false;
235    }
236  977 input.mark(4);
237   
238    // get first 2 bytes or return false
239  977 byte[] bytes = new byte[2];
240  977 int read = input.read(bytes);
241  977 input.reset();
242  977 if (read != bytes.length)
243    {
244  0 return false;
245    }
246   
247  977 int header = (bytes[0] & 0xff) | ((bytes[1] << 8) & 0xff00);
248  977 return (GZIPInputStream.GZIP_MAGIC == header);
249    }
250   
251    /**
252    * Returns a Reader for the given input after wrapping it in a buffered input
253    * stream, and then checking if it needs to be wrapped by a GZipInputStream
254    *
255    * @param input
256    * @return
257    */
 
258  975 toggle private BufferedReader checkForGzipStream(InputStream input)
259    throws Exception
260    {
261    // NB: stackoverflow
262    // https://stackoverflow.com/questions/4818468/how-to-check-if-inputstream-is-gzipped
263    // could use a PushBackInputStream rather than a BufferedInputStream
264  975 if (!input.markSupported())
265    {
266  973 input = new BufferedInputStream(input, 16);
267    }
268  975 if (isGzipStream(input))
269    {
270  2 return getGzipReader(input);
271    }
272    // return a buffered reader for the stream.
273  973 InputStreamReader isReader = new InputStreamReader(input);
274  973 BufferedReader toReadFrom = new BufferedReader(isReader);
275  973 return toReadFrom;
276    }
277   
278    /**
279    * Returns a {@code BufferedReader} which wraps the input stream with a
280    * GZIPInputStream. Throws a {@code ZipException} if a GZIP format error
281    * occurs or the compression method used is unsupported.
282    *
283    * @param inputStream
284    * @return
285    * @throws Exception
286    */
 
287  2 toggle private BufferedReader getGzipReader(InputStream inputStream)
288    throws Exception
289    {
290  2 BufferedReader inData = new BufferedReader(
291    new InputStreamReader(new GZIPInputStream(inputStream)));
292  2 inData.mark(2048);
293  2 inData.read();
294  2 inData.reset();
295  2 return inData;
296    }
297   
298    /**
299    * Tries to read from the given URL. If successful, saves a reader to the
300    * response in field {@code dataIn}, otherwise (on exception, or HTTP response
301    * status not 200), throws an exception.
302    * <p>
303    * If the response status includes
304    *
305    * <pre>
306    * Content-Type : application/x-gzip
307    * </pre>
308    *
309    * then tries to read as gzipped content.
310    *
311    * @param urlStr
312    * @throws IOException
313    * @throws MalformedURLException
314    */
 
315  14 toggle private void checkURLSource(String urlStr)
316    throws IOException, MalformedURLException
317    {
318  14 errormessage = "URL NOT FOUND";
319  14 URL url = new URL(urlStr);
320  14 URLConnection _conn = HttpUtils.openConnection(url);
321  14 if (_conn instanceof HttpURLConnection)
322    {
323  12 HttpURLConnection conn = HttpUtils
324    .followConnection((HttpURLConnection) _conn);
325  12 int rc = conn.getResponseCode();
326  12 if (rc != HttpURLConnection.HTTP_OK)
327    {
328  0 throw new FileNotFoundException("Response status from " + urlStr
329    + " was " + conn.getResponseCode());
330    }
331  12 _conn = conn;
332    }
333    else
334    {
335  2 try
336    {
337  2 dataIn = checkForGzipStream(_conn.getInputStream());
338  2 dataName = urlStr;
339    } catch (IOException ex)
340    {
341  0 throw new IOException("Failed to handle non-HTTP URI stream", ex);
342    } catch (Exception ex)
343    {
344  0 throw new IOException(
345    "Failed to determine type of input stream for given URI",
346    ex);
347    }
348  2 return;
349    }
350  12 String encoding = _conn.getContentEncoding();
351  12 String contentType = _conn.getContentType();
352  12 boolean isgzipped = false;
353  12 isgzipped |=(contentType!=null && ("application/x-gzip".equalsIgnoreCase(contentType) || contentType.endsWith("gzip")));
354   
355  12 isgzipped |= (encoding!=null && "gzip".equals(encoding));
356   
357  12 Exception e = null;
358   
359  12 InputStream inputStream = _conn.getInputStream();
360  12 if (isgzipped)
361    {
362  0 try
363    {
364  0 dataIn = getGzipReader(inputStream);
365  0 dataName = urlStr;
366    } catch (Exception e1)
367    {
368  0 throw new IOException(MessageManager
369    .getString("exception.failed_to_resolve_gzip_stream"), e);
370    }
371  0 return;
372    }
373   
374  12 dataIn = new BufferedReader(new InputStreamReader(inputStream));
375  12 dataName = urlStr;
376  12 return;
377    }
378   
379    /**
380    * sets the suffix string (if any) and returns remainder (if suffix was
381    * detected)
382    *
383    * @param fileStr
384    * @return truncated fileStr or null
385    */
 
386  14 toggle private String extractSuffix(String fileStr)
387    {
388    // first check that there wasn't a suffix string tagged on.
389  14 int sfpos = fileStr.lastIndexOf(suffixSeparator);
390  14 if (sfpos > -1 && sfpos < fileStr.length() - 1)
391    {
392  0 suffix = fileStr.substring(sfpos + 1);
393    // jalview.bin.Console.errPrintln("DEBUG: Found Suffix:"+suffix);
394  0 return fileStr.substring(0, sfpos);
395    }
396  14 return null;
397    }
398   
399    /**
400    * not for general use, creates a fileParse object for an existing reader with
401    * configurable values for the origin and the type of the source
402    */
 
403  0 toggle public FileParse(BufferedReader source, String originString,
404    DataSourceType sourceType)
405    {
406  0 dataSourceType = sourceType;
407  0 error = false;
408  0 inFile = null;
409  0 dataName = originString;
410  0 dataIn = source;
411  0 try
412    {
413  0 if (dataIn.markSupported())
414    {
415  0 dataIn.mark(READAHEAD_LIMIT);
416    }
417    } catch (IOException q)
418    {
419   
420    }
421    }
422   
423    /**
424    * Create a datasource for input to Jalview. See AppletFormatAdapter for the
425    * types of sources that are handled.
426    *
427    * @param file
428    * - datasource locator/content as File or String
429    * @param sourceType
430    * - protocol of source
431    * @throws MalformedURLException
432    * @throws IOException
433    */
 
434  1676 toggle public FileParse(Object file, DataSourceType sourceType)
435    throws MalformedURLException, FileNotFoundException, IOException
436    {
437  1676 if (file instanceof File)
438    {
439  16 parse((File) file, ((File) file).getPath(), sourceType, true);
440    }
441    else
442    {
443  1660 parse(null, file.toString(), sourceType, false);
444    }
445    }
446   
 
447  1676 toggle private void parse(File file, String fileStr, DataSourceType sourceType,
448    boolean isFileObject) throws FileNotFoundException, IOException
449    {
450  1676 bytes = Platform.getFileBytes(file);
451  1676 dataSourceType = sourceType;
452  1676 error = false;
453  1676 boolean filenotfound = false;
454   
455  1676 if (sourceType == DataSourceType.FILE)
456    {
457   
458  973 if (bytes != null)
459    {
460    // this will be from JavaScript
461  0 inFile = file;
462  0 dataIn = new BufferedReader(
463    new InputStreamReader(new ByteArrayInputStream(bytes)));
464  0 dataName = fileStr;
465    }
466  973 else if (checkFileSource(fileStr))
467    {
468  0 String suffixLess = extractSuffix(fileStr);
469  0 if (suffixLess != null)
470    {
471  0 if (checkFileSource(suffixLess))
472    {
473  0 throw new IOException(MessageManager.formatMessage(
474    "exception.problem_opening_file_also_tried",
475    new String[]
476    { inFile.getName(), suffixLess, errormessage }));
477    }
478    }
479    else
480    {
481  0 throw new IOException(MessageManager.formatMessage(
482    "exception.problem_opening_file", new String[]
483    { inFile.getName(), errormessage }));
484    }
485    }
486    }
487  703 else if (sourceType == DataSourceType.RELATIVE_URL)
488    {
489    // BH 2018 hack for no support for access-origin
490  0 bytes = Platform.getFileAsBytes(fileStr);
491  0 dataIn = new BufferedReader(
492    new InputStreamReader(new ByteArrayInputStream(bytes)));
493  0 dataName = fileStr;
494   
495    }
496  703 else if (sourceType == DataSourceType.URL)
497    {
498  14 try
499    {
500  14 try
501    {
502  14 checkURLSource(fileStr);
503  14 if (suffixSeparator == '#')
504    {
505  14 extractSuffix(fileStr); // URL lref is stored for later reference.
506    }
507    } catch (IOException e)
508    {
509  0 String suffixLess = extractSuffix(fileStr);
510  0 if (suffixLess == null)
511    {
512  0 if (e instanceof FileNotFoundException
513    || e instanceof UnknownHostException
514    || e instanceof SocketTimeoutException)
515    {
516  0 errormessage = "File at URL '" + fileStr + "' not found";
517  0 filenotfound = true;
518    }
519  0 throw (e);
520    }
521    else
522    {
523  0 try
524    {
525  0 checkURLSource(suffixLess);
526    } catch (IOException e2)
527    {
528  0 errormessage = "BAD URL WITH OR WITHOUT SUFFIX '" + fileStr
529    + "'";
530  0 if (e instanceof FileNotFoundException
531    || e instanceof UnknownHostException
532    || e instanceof SocketTimeoutException)
533    {
534  0 filenotfound = true;
535    }
536  0 throw (e); // just pass back original - everything was wrong.
537    }
538    }
539    }
540    } catch (Exception e)
541    {
542  0 errormessage = "CANNOT ACCESS DATA AT URL '" + fileStr + "' ("
543    + e.getMessage() + ")";
544  0 error = true;
545    }
546    }
547  689 else if (sourceType == DataSourceType.PASTE)
548    {
549  325 errormessage = "PASTE INACCESSIBLE!";
550  325 dataIn = new BufferedReader(new StringReader(fileStr));
551  325 dataName = "Paste";
552    }
553  364 else if (sourceType == DataSourceType.CLASSLOADER)
554    {
555  364 errormessage = "RESOURCE CANNOT BE LOCATED";
556  364 InputStream is = getClass().getResourceAsStream("/" + fileStr);
557  364 if (is == null)
558    {
559  0 String suffixLess = extractSuffix(fileStr);
560  0 if (suffixLess != null)
561    {
562  0 is = getClass().getResourceAsStream("/" + suffixLess);
563    }
564    }
565  364 if (is != null)
566    {
567  364 dataIn = new BufferedReader(new InputStreamReader(is));
568  364 dataName = fileStr;
569    }
570    else
571    {
572  0 error = true;
573    }
574    }
575    else
576    {
577  0 errormessage = "PROBABLE IMPLEMENTATION ERROR : Datasource Type given as '"
578  0 + (sourceType != null ? sourceType : "null") + "'";
579  0 error = true;
580    }
581  1676 if (dataIn == null || error)
582    {
583    // pass up the reason why we have no source to read from
584  0 if (filenotfound)
585    {
586  0 throw new FileNotFoundException(MessageManager
587    .formatMessage("label.url_not_found", new String[]
588    { errormessage }));
589    }
590  0 throw new IOException(MessageManager.formatMessage(
591    "exception.failed_to_read_data_from_source", new String[]
592    { errormessage }));
593    }
594  1676 error = false;
595  1676 dataIn.mark(READAHEAD_LIMIT);
596    }
597   
598    /**
599    * mark the current position in the source as start for the purposes of it
600    * being analysed by IdentifyFile().identify
601    *
602    * @throws IOException
603    */
 
604  914 toggle public void mark() throws IOException
605    {
606  914 if (dataIn != null)
607    {
608  914 dataIn.mark(READAHEAD_LIMIT);
609    }
610    else
611    {
612  0 throw new IOException(
613    MessageManager.getString("exception.no_init_source_stream"));
614    }
615    }
616   
 
617  87371 toggle public String nextLine() throws IOException
618    {
619  87374 if (!error)
620    {
621  87376 return dataIn.readLine();
622    }
623  0 throw new IOException(MessageManager
624    .formatMessage("exception.invalid_source_stream", new String[]
625    { errormessage }));
626    }
627   
628    /**
629    *
630    * @return true if this FileParse is configured for Export only
631    */
 
632  0 toggle public boolean isExporting()
633    {
634  0 return !error && dataIn == null;
635    }
636   
637    /**
638    *
639    * @return true if the data source is valid
640    */
 
641  476 toggle public boolean isValid()
642    {
643  476 return !error;
644    }
645   
646    /**
647    * closes the datasource and tidies up. source will be left in an error state
648    */
 
649  461 toggle public void close() throws IOException
650    {
651  461 errormessage = "EXCEPTION ON CLOSE";
652  461 error = true;
653  461 dataIn.close();
654  461 dataIn = null;
655  461 errormessage = "SOURCE IS CLOSED";
656    }
657   
658    /**
659    * Rewinds the datasource to the marked point if possible
660    *
661    * @param bytesRead
662    *
663    */
 
664  0 toggle public void reset(int bytesRead) throws IOException
665    {
666  0 if (bytesRead >= READAHEAD_LIMIT)
667    {
668  0 jalview.bin.Console.errPrintln(String.format(
669    "File reset error: read %d bytes but reset limit is %d",
670    bytesRead, READAHEAD_LIMIT));
671    }
672  0 if (dataIn != null && !error)
673    {
674  0 dataIn.reset();
675    }
676    else
677    {
678  0 throw new IOException(MessageManager.getString(
679    "error.implementation_error_reset_called_for_invalid_source"));
680    }
681    }
682   
683    /**
684    *
685    * @return true if there is a warning for the user
686    */
 
687  180 toggle public boolean hasWarningMessage()
688    {
689  180 return (warningMessage != null && warningMessage.length() > 0);
690    }
691   
692    /**
693    *
694    * @return empty string or warning message about file that was just parsed.
695    */
 
696  9 toggle public String getWarningMessage()
697    {
698  9 return warningMessage;
699    }
700   
 
701  264 toggle public String getInFile()
702    {
703  264 if (inFile != null)
704    {
705  242 return inFile.getAbsolutePath() + " (" + index + ")";
706    }
707    else
708    {
709  22 return "From Paste + (" + index + ")";
710    }
711    }
712   
713    /**
714    * @return the dataName
715    */
 
716  880 toggle public String getDataName()
717    {
718  880 return dataName;
719    }
720   
721    /**
722    * set the (human readable) name or URI for this datasource
723    *
724    * @param dataname
725    */
 
726  0 toggle protected void setDataName(String dataname)
727    {
728  0 dataName = dataname;
729    }
730   
731    /**
732    * get the underlying bufferedReader for this data source.
733    *
734    * @return null if no reader available
735    * @throws IOException
736    */
 
737  260 toggle public Reader getReader()
738    {
739  260 if (dataIn != null) // Probably don't need to test for readiness &&
740    // dataIn.ready())
741    {
742  260 return dataIn;
743    }
744  0 return null;
745    }
746   
 
747  29 toggle public AlignViewportI getViewport()
748    {
749  29 return viewport;
750    }
751   
 
752  128 toggle public void setViewport(AlignViewportI viewport)
753    {
754  128 this.viewport = viewport;
755    }
756   
757    /**
758    * @return the currently configured exportSettings for writing data.
759    */
 
760  8 toggle public AlignExportSettingsI getExportSettings()
761    {
762  8 return exportSettings;
763    }
764   
765    /**
766    * Set configuration for export of data.
767    *
768    * @param exportSettings
769    * the exportSettings to set
770    */
 
771  177 toggle public void setExportSettings(AlignExportSettingsI exportSettings)
772    {
773  177 this.exportSettings = exportSettings;
774    }
775   
776    /**
777    * method overridden by complex file exporter/importers which support
778    * exporting visualisation and layout settings for a view
779    *
780    * @param avpanel
781    */
 
782  176 toggle public void configureForView(AlignmentViewPanel avpanel)
783    {
784  176 if (avpanel != null)
785    {
786  128 setViewport(avpanel.getAlignViewport());
787    }
788    // could also set export/import settings
789    }
790   
791    /**
792    * Returns the preferred feature colour configuration if there is one, else
793    * null
794    *
795    * @return
796    */
 
797  312 toggle public FeatureSettingsModelI getFeatureColourScheme()
798    {
799  312 return null;
800    }
801   
 
802  0 toggle public DataSourceType getDataSourceType()
803    {
804  0 return dataSourceType;
805    }
806   
807    /**
808    * Returns a buffered reader for the input object. Returns null, or throws
809    * IOException, on failure.
810    *
811    * @param file
812    * a File, or a String which is a name of a file
813    * @param sourceType
814    * @return
815    * @throws IOException
816    */
 
817  36 toggle public BufferedReader getBufferedReader(Object file,
818    DataSourceType sourceType) throws IOException
819    {
820  36 BufferedReader in = null;
821  36 byte[] bytes;
822   
823  36 switch (sourceType)
824    {
825  17 case FILE:
826  17 if (file instanceof String)
827    {
828  17 return new BufferedReader(new FileReader((String) file));
829    }
830  0 bytes = Platform.getFileBytes((File) file);
831  0 if (bytes != null)
832    {
833  0 return new BufferedReader(
834    new InputStreamReader(new ByteArrayInputStream(bytes)));
835    }
836  0 return new BufferedReader(new FileReader((File) file));
837  0 case URL:
838  0 URL url = new URL(file.toString());
839  0 in = new BufferedReader(
840    new InputStreamReader(HttpUtils.openStream(url)));
841  0 break;
842  0 case RELATIVE_URL: // JalviewJS only
843  0 bytes = Platform.getFileAsBytes(file.toString());
844  0 if (bytes != null)
845    {
846  0 in = new BufferedReader(
847    new InputStreamReader(new ByteArrayInputStream(bytes)));
848    }
849  0 break;
850  19 case PASTE:
851  19 in = new BufferedReader(new StringReader(file.toString()));
852  19 break;
853  0 case CLASSLOADER:
854  0 InputStream is = getClass().getResourceAsStream("/" + file);
855  0 if (is != null)
856    {
857  0 in = new BufferedReader(new InputStreamReader(is));
858    }
859  0 break;
860    }
861   
862  19 return in;
863    }
864    }