Clover icon

Coverage Report

  1. Project Clover database Mon Sep 2 2024 17:57:51 BST
  2. Package jalview.io

File FileParse.java

 

Coverage histogram

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

Code metrics

94
231
34
1
860
576
101
0.44
6.79
34
2.97

Classes

Class Line # Actions
FileParse 56 231 101
0.5153203651.5%
 

Contributing tests

This file is covered by 317 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  262 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  840 toggle public FileParse(FileParse from) throws IOException
146    {
147  840 if (from == null)
148    {
149  0 throw new Error(MessageManager
150    .getString("error.implementation_error_null_fileparse"));
151    }
152  840 if (from == this)
153    {
154  0 return;
155    }
156  840 index = ++from.index;
157  840 inFile = from.inFile;
158  840 suffixSeparator = from.suffixSeparator;
159  840 suffix = from.suffix;
160  840 errormessage = from.errormessage; // inherit potential error messages
161  840 error = false; // reset any error condition.
162  840 dataSourceType = from.dataSourceType;
163  840 dataIn = from.dataIn;
164  840 if (dataIn != null)
165    {
166  840 mark();
167    }
168  840 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  860 toggle private boolean checkFileSource(String fileStr) throws IOException
179    {
180  860 error = false;
181  860 this.inFile = new File(fileStr);
182    // check to see if it's a Jar file in disguise.
183  860 if (!inFile.exists())
184    {
185  0 errormessage = "FILE NOT FOUND";
186  0 error = true;
187    }
188  860 if (!inFile.canRead())
189    {
190  0 errormessage = "FILE CANNOT BE OPENED FOR READING";
191  0 error = true;
192    }
193  860 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  860 if (!error)
201    {
202  860 try
203    {
204  860 dataIn = checkForGzipStream(new FileInputStream(fileStr));
205  860 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  860 ;
214    }
215  860 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  865 toggle public static boolean isGzipStream(InputStream input) throws IOException
229    {
230  865 if (!input.markSupported())
231    {
232  1 Console.error(
233    "FileParse.izGzipStream: input stream must support mark/reset");
234  1 return false;
235    }
236  864 input.mark(4);
237   
238    // get first 2 bytes or return false
239  864 byte[] bytes = new byte[2];
240  864 int read = input.read(bytes);
241  864 input.reset();
242  864 if (read != bytes.length)
243    {
244  0 return false;
245    }
246   
247  864 int header = (bytes[0] & 0xff) | ((bytes[1] << 8) & 0xff00);
248  864 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  862 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  862 if (!input.markSupported())
265    {
266  860 input = new BufferedInputStream(input, 16);
267    }
268  862 if (isGzipStream(input))
269    {
270  2 return getGzipReader(input);
271    }
272    // return a buffered reader for the stream.
273  860 InputStreamReader isReader = new InputStreamReader(input);
274  860 BufferedReader toReadFrom = new BufferedReader(isReader);
275  860 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  2 toggle private void checkURLSource(String urlStr)
316    throws IOException, MalformedURLException
317    {
318  2 errormessage = "URL NOT FOUND";
319  2 URL url = new URL(urlStr);
320  2 URLConnection _conn = HttpUtils.openConnection(url);
321  2 if (_conn instanceof HttpURLConnection)
322    {
323  0 HttpURLConnection conn = HttpUtils
324    .followConnection((HttpURLConnection) _conn);
325  0 int rc = conn.getResponseCode();
326  0 if (rc != HttpURLConnection.HTTP_OK)
327    {
328  0 throw new FileNotFoundException("Response status from " + urlStr
329    + " was " + conn.getResponseCode());
330    }
331  0 _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  0 String encoding = _conn.getContentEncoding();
351  0 String contentType = _conn.getContentType();
352  0 boolean isgzipped = "application/x-gzip".equalsIgnoreCase(contentType)
353    || contentType.endsWith("gzip") || "gzip".equals(encoding);
354  0 Exception e = null;
355  0 InputStream inputStream = _conn.getInputStream();
356  0 if (isgzipped)
357    {
358  0 try
359    {
360  0 dataIn = getGzipReader(inputStream);
361  0 dataName = urlStr;
362    } catch (Exception e1)
363    {
364  0 throw new IOException(MessageManager
365    .getString("exception.failed_to_resolve_gzip_stream"), e);
366    }
367  0 return;
368    }
369   
370  0 dataIn = new BufferedReader(new InputStreamReader(inputStream));
371  0 dataName = urlStr;
372  0 return;
373    }
374   
375    /**
376    * sets the suffix string (if any) and returns remainder (if suffix was
377    * detected)
378    *
379    * @param fileStr
380    * @return truncated fileStr or null
381    */
 
382  2 toggle private String extractSuffix(String fileStr)
383    {
384    // first check that there wasn't a suffix string tagged on.
385  2 int sfpos = fileStr.lastIndexOf(suffixSeparator);
386  2 if (sfpos > -1 && sfpos < fileStr.length() - 1)
387    {
388  0 suffix = fileStr.substring(sfpos + 1);
389    // jalview.bin.Console.errPrintln("DEBUG: Found Suffix:"+suffix);
390  0 return fileStr.substring(0, sfpos);
391    }
392  2 return null;
393    }
394   
395    /**
396    * not for general use, creates a fileParse object for an existing reader with
397    * configurable values for the origin and the type of the source
398    */
 
399  0 toggle public FileParse(BufferedReader source, String originString,
400    DataSourceType sourceType)
401    {
402  0 dataSourceType = sourceType;
403  0 error = false;
404  0 inFile = null;
405  0 dataName = originString;
406  0 dataIn = source;
407  0 try
408    {
409  0 if (dataIn.markSupported())
410    {
411  0 dataIn.mark(READAHEAD_LIMIT);
412    }
413    } catch (IOException q)
414    {
415   
416    }
417    }
418   
419    /**
420    * Create a datasource for input to Jalview. See AppletFormatAdapter for the
421    * types of sources that are handled.
422    *
423    * @param file
424    * - datasource locator/content as File or String
425    * @param sourceType
426    * - protocol of source
427    * @throws MalformedURLException
428    * @throws IOException
429    */
 
430  1492 toggle public FileParse(Object file, DataSourceType sourceType)
431    throws MalformedURLException, FileNotFoundException, IOException
432    {
433  1492 if (file instanceof File)
434    {
435  16 parse((File) file, ((File) file).getPath(), sourceType, true);
436    }
437    else
438    {
439  1476 parse(null, file.toString(), sourceType, false);
440    }
441    }
442   
 
443  1492 toggle private void parse(File file, String fileStr, DataSourceType sourceType,
444    boolean isFileObject) throws FileNotFoundException, IOException
445    {
446  1492 bytes = Platform.getFileBytes(file);
447  1492 dataSourceType = sourceType;
448  1492 error = false;
449  1492 boolean filenotfound = false;
450   
451  1492 if (sourceType == DataSourceType.FILE)
452    {
453   
454  860 if (bytes != null)
455    {
456    // this will be from JavaScript
457  0 inFile = file;
458  0 dataIn = new BufferedReader(
459    new InputStreamReader(new ByteArrayInputStream(bytes)));
460  0 dataName = fileStr;
461    }
462  860 else if (checkFileSource(fileStr))
463    {
464  0 String suffixLess = extractSuffix(fileStr);
465  0 if (suffixLess != null)
466    {
467  0 if (checkFileSource(suffixLess))
468    {
469  0 throw new IOException(MessageManager.formatMessage(
470    "exception.problem_opening_file_also_tried",
471    new String[]
472    { inFile.getName(), suffixLess, errormessage }));
473    }
474    }
475    else
476    {
477  0 throw new IOException(MessageManager.formatMessage(
478    "exception.problem_opening_file", new String[]
479    { inFile.getName(), errormessage }));
480    }
481    }
482    }
483  632 else if (sourceType == DataSourceType.RELATIVE_URL)
484    {
485    // BH 2018 hack for no support for access-origin
486  0 bytes = Platform.getFileAsBytes(fileStr);
487  0 dataIn = new BufferedReader(
488    new InputStreamReader(new ByteArrayInputStream(bytes)));
489  0 dataName = fileStr;
490   
491    }
492  632 else if (sourceType == DataSourceType.URL)
493    {
494  2 try
495    {
496  2 try
497    {
498  2 checkURLSource(fileStr);
499  2 if (suffixSeparator == '#')
500    {
501  2 extractSuffix(fileStr); // URL lref is stored for later reference.
502    }
503    } catch (IOException e)
504    {
505  0 String suffixLess = extractSuffix(fileStr);
506  0 if (suffixLess == null)
507    {
508  0 if (e instanceof FileNotFoundException
509    || e instanceof UnknownHostException
510    || e instanceof SocketTimeoutException)
511    {
512  0 errormessage = "File at URL '" + fileStr + "' not found";
513  0 filenotfound = true;
514    }
515  0 throw (e);
516    }
517    else
518    {
519  0 try
520    {
521  0 checkURLSource(suffixLess);
522    } catch (IOException e2)
523    {
524  0 errormessage = "BAD URL WITH OR WITHOUT SUFFIX '" + fileStr
525    + "'";
526  0 if (e instanceof FileNotFoundException
527    || e instanceof UnknownHostException
528    || e instanceof SocketTimeoutException)
529    {
530  0 filenotfound = true;
531    }
532  0 throw (e); // just pass back original - everything was wrong.
533    }
534    }
535    }
536    } catch (Exception e)
537    {
538  0 errormessage = "CANNOT ACCESS DATA AT URL '" + fileStr + "' ("
539    + e.getMessage() + ")";
540  0 error = true;
541    }
542    }
543  630 else if (sourceType == DataSourceType.PASTE)
544    {
545  310 errormessage = "PASTE INACCESSIBLE!";
546  310 dataIn = new BufferedReader(new StringReader(fileStr));
547  310 dataName = "Paste";
548    }
549  320 else if (sourceType == DataSourceType.CLASSLOADER)
550    {
551  319 errormessage = "RESOURCE CANNOT BE LOCATED";
552  320 InputStream is = getClass().getResourceAsStream("/" + fileStr);
553  320 if (is == null)
554    {
555  0 String suffixLess = extractSuffix(fileStr);
556  0 if (suffixLess != null)
557    {
558  0 is = getClass().getResourceAsStream("/" + suffixLess);
559    }
560    }
561  320 if (is != null)
562    {
563  320 dataIn = new BufferedReader(new InputStreamReader(is));
564  320 dataName = fileStr;
565    }
566    else
567    {
568  0 error = true;
569    }
570    }
571    else
572    {
573  0 errormessage = "PROBABLE IMPLEMENTATION ERROR : Datasource Type given as '"
574  0 + (sourceType != null ? sourceType : "null") + "'";
575  0 error = true;
576    }
577  1492 if (dataIn == null || error)
578    {
579    // pass up the reason why we have no source to read from
580  0 if (filenotfound)
581    {
582  0 throw new FileNotFoundException(MessageManager
583    .formatMessage("label.url_not_found", new String[]
584    { errormessage }));
585    }
586  0 throw new IOException(MessageManager.formatMessage(
587    "exception.failed_to_read_data_from_source", new String[]
588    { errormessage }));
589    }
590  1492 error = false;
591  1492 dataIn.mark(READAHEAD_LIMIT);
592    }
593   
594    /**
595    * mark the current position in the source as start for the purposes of it
596    * being analysed by IdentifyFile().identify
597    *
598    * @throws IOException
599    */
 
600  844 toggle public void mark() throws IOException
601    {
602  844 if (dataIn != null)
603    {
604  844 dataIn.mark(READAHEAD_LIMIT);
605    }
606    else
607    {
608  0 throw new IOException(
609    MessageManager.getString("exception.no_init_source_stream"));
610    }
611    }
612   
 
613  84077 toggle public String nextLine() throws IOException
614    {
615  84079 if (!error)
616    {
617  84079 return dataIn.readLine();
618    }
619  0 throw new IOException(MessageManager
620    .formatMessage("exception.invalid_source_stream", new String[]
621    { errormessage }));
622    }
623   
624    /**
625    *
626    * @return true if this FileParse is configured for Export only
627    */
 
628  0 toggle public boolean isExporting()
629    {
630  0 return !error && dataIn == null;
631    }
632   
633    /**
634    *
635    * @return true if the data source is valid
636    */
 
637  437 toggle public boolean isValid()
638    {
639  437 return !error;
640    }
641   
642    /**
643    * closes the datasource and tidies up. source will be left in an error state
644    */
 
645  422 toggle public void close() throws IOException
646    {
647  422 errormessage = "EXCEPTION ON CLOSE";
648  422 error = true;
649  422 dataIn.close();
650  422 dataIn = null;
651  422 errormessage = "SOURCE IS CLOSED";
652    }
653   
654    /**
655    * Rewinds the datasource to the marked point if possible
656    *
657    * @param bytesRead
658    *
659    */
 
660  0 toggle public void reset(int bytesRead) throws IOException
661    {
662  0 if (bytesRead >= READAHEAD_LIMIT)
663    {
664  0 jalview.bin.Console.errPrintln(String.format(
665    "File reset error: read %d bytes but reset limit is %d",
666    bytesRead, READAHEAD_LIMIT));
667    }
668  0 if (dataIn != null && !error)
669    {
670  0 dataIn.reset();
671    }
672    else
673    {
674  0 throw new IOException(MessageManager.getString(
675    "error.implementation_error_reset_called_for_invalid_source"));
676    }
677    }
678   
679    /**
680    *
681    * @return true if there is a warning for the user
682    */
 
683  180 toggle public boolean hasWarningMessage()
684    {
685  180 return (warningMessage != null && warningMessage.length() > 0);
686    }
687   
688    /**
689    *
690    * @return empty string or warning message about file that was just parsed.
691    */
 
692  9 toggle public String getWarningMessage()
693    {
694  9 return warningMessage;
695    }
696   
 
697  0 toggle public String getInFile()
698    {
699  0 if (inFile != null)
700    {
701  0 return inFile.getAbsolutePath() + " (" + index + ")";
702    }
703    else
704    {
705  0 return "From Paste + (" + index + ")";
706    }
707    }
708   
709    /**
710    * @return the dataName
711    */
 
712  633 toggle public String getDataName()
713    {
714  633 return dataName;
715    }
716   
717    /**
718    * set the (human readable) name or URI for this datasource
719    *
720    * @param dataname
721    */
 
722  0 toggle protected void setDataName(String dataname)
723    {
724  0 dataName = dataname;
725    }
726   
727    /**
728    * get the underlying bufferedReader for this data source.
729    *
730    * @return null if no reader available
731    * @throws IOException
732    */
 
733  190 toggle public Reader getReader()
734    {
735  190 if (dataIn != null) // Probably don't need to test for readiness &&
736    // dataIn.ready())
737    {
738  190 return dataIn;
739    }
740  0 return null;
741    }
742   
 
743  29 toggle public AlignViewportI getViewport()
744    {
745  29 return viewport;
746    }
747   
 
748  128 toggle public void setViewport(AlignViewportI viewport)
749    {
750  128 this.viewport = viewport;
751    }
752   
753    /**
754    * @return the currently configured exportSettings for writing data.
755    */
 
756  8 toggle public AlignExportSettingsI getExportSettings()
757    {
758  8 return exportSettings;
759    }
760   
761    /**
762    * Set configuration for export of data.
763    *
764    * @param exportSettings
765    * the exportSettings to set
766    */
 
767  177 toggle public void setExportSettings(AlignExportSettingsI exportSettings)
768    {
769  177 this.exportSettings = exportSettings;
770    }
771   
772    /**
773    * method overridden by complex file exporter/importers which support
774    * exporting visualisation and layout settings for a view
775    *
776    * @param avpanel
777    */
 
778  176 toggle public void configureForView(AlignmentViewPanel avpanel)
779    {
780  176 if (avpanel != null)
781    {
782  128 setViewport(avpanel.getAlignViewport());
783    }
784    // could also set export/import settings
785    }
786   
787    /**
788    * Returns the preferred feature colour configuration if there is one, else
789    * null
790    *
791    * @return
792    */
 
793  297 toggle public FeatureSettingsModelI getFeatureColourScheme()
794    {
795  297 return null;
796    }
797   
 
798  0 toggle public DataSourceType getDataSourceType()
799    {
800  0 return dataSourceType;
801    }
802   
803    /**
804    * Returns a buffered reader for the input object. Returns null, or throws
805    * IOException, on failure.
806    *
807    * @param file
808    * a File, or a String which is a name of a file
809    * @param sourceType
810    * @return
811    * @throws IOException
812    */
 
813  26 toggle public BufferedReader getBufferedReader(Object file,
814    DataSourceType sourceType) throws IOException
815    {
816  26 BufferedReader in = null;
817  26 byte[] bytes;
818   
819  26 switch (sourceType)
820    {
821  11 case FILE:
822  11 if (file instanceof String)
823    {
824  11 return new BufferedReader(new FileReader((String) file));
825    }
826  0 bytes = Platform.getFileBytes((File) file);
827  0 if (bytes != null)
828    {
829  0 return new BufferedReader(
830    new InputStreamReader(new ByteArrayInputStream(bytes)));
831    }
832  0 return new BufferedReader(new FileReader((File) file));
833  0 case URL:
834  0 URL url = new URL(file.toString());
835  0 in = new BufferedReader(
836    new InputStreamReader(HttpUtils.openStream(url)));
837  0 break;
838  0 case RELATIVE_URL: // JalviewJS only
839  0 bytes = Platform.getFileAsBytes(file.toString());
840  0 if (bytes != null)
841    {
842  0 in = new BufferedReader(
843    new InputStreamReader(new ByteArrayInputStream(bytes)));
844    }
845  0 break;
846  15 case PASTE:
847  15 in = new BufferedReader(new StringReader(file.toString()));
848  15 break;
849  0 case CLASSLOADER:
850  0 InputStream is = getClass().getResourceAsStream("/" + file);
851  0 if (is != null)
852    {
853  0 in = new BufferedReader(new InputStreamReader(is));
854    }
855  0 break;
856    }
857   
858  15 return in;
859    }
860    }