Clover icon

Coverage Report

  1. Project Clover database Thu Aug 13 2020 12:04:21 BST
  2. Package jalview.io

File FileLoader.java

 

Coverage histogram

../../img/srcFileCovDistChart7.png
27% of files have more coverage

Code metrics

82
167
17
1
638
453
69
0.41
9.82
17
4.06

Classes

Class Line # Actions
FileLoader 51 167 69
0.616541361.7%
 

Contributing tests

This file is covered by 68 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.File;
24    import java.io.IOException;
25    import java.util.StringTokenizer;
26    import java.util.Vector;
27   
28    import javax.swing.SwingUtilities;
29   
30    import jalview.api.ComplexAlignFile;
31    import jalview.api.FeatureSettingsModelI;
32    import jalview.api.FeaturesDisplayedI;
33    import jalview.api.FeaturesSourceI;
34    import jalview.bin.Cache;
35    import jalview.bin.Jalview;
36    import jalview.datamodel.AlignmentI;
37    import jalview.datamodel.HiddenColumns;
38    import jalview.datamodel.PDBEntry;
39    import jalview.datamodel.SequenceI;
40    import jalview.gui.AlignFrame;
41    import jalview.gui.AlignViewport;
42    import jalview.gui.Desktop;
43    import jalview.gui.JvOptionPane;
44    import jalview.json.binding.biojson.v1.ColourSchemeMapper;
45    import jalview.project.Jalview2XML;
46    import jalview.schemes.ColourSchemeI;
47    import jalview.structure.StructureSelectionManager;
48    import jalview.util.MessageManager;
49    import jalview.ws.utils.UrlDownloadClient;
50   
 
51    public class FileLoader implements Runnable
52    {
53    String file;
54   
55    DataSourceType protocol;
56   
57    FileFormatI format;
58   
59    AlignmentFileReaderI source = null; // alternative specification of where data
60    // comes
61   
62    // from
63   
64    AlignViewport viewport;
65   
66    AlignFrame alignFrame;
67   
68    long loadtime;
69   
70    long memused;
71   
72    boolean raiseGUI = true;
73   
74    private File selectedFile;
75   
76    /**
77    * default constructor always raised errors in GUI dialog boxes
78    */
 
79  87 toggle public FileLoader()
80    {
81  87 this(true);
82    }
83   
84    /**
85    * construct a Fileloader that may raise errors non-interactively
86    *
87    * @param raiseGUI
88    * true if errors are to be raised as GUI dialog boxes
89    */
 
90  143 toggle public FileLoader(boolean raiseGUI)
91    {
92  143 this.raiseGUI = raiseGUI;
93    }
94   
 
95  1 toggle public void LoadFile(AlignViewport viewport, Object file,
96    DataSourceType protocol, FileFormatI format)
97    {
98  1 this.viewport = viewport;
99  1 if (file instanceof File) {
100  0 this.selectedFile = (File) file;
101  0 file = selectedFile.getPath();
102    }
103  1 LoadFile(file.toString(), protocol, format);
104    }
105   
 
106  1 toggle public void LoadFile(String file, DataSourceType protocol,
107    FileFormatI format)
108    {
109  1 this.file = file;
110  1 this.protocol = protocol;
111  1 this.format = format;
112   
113  1 final Thread loader = new Thread(this);
114   
115  1 SwingUtilities.invokeLater(new Runnable()
116    {
 
117  1 toggle @Override
118    public void run()
119    {
120  1 loader.start();
121    }
122    });
123    }
124   
125    /**
126    * Load a (file, protocol) source of unknown type
127    *
128    * @param file
129    * @param protocol
130    */
 
131  0 toggle public void LoadFile(String file, DataSourceType protocol)
132    {
133  0 LoadFile(file, protocol, null);
134    }
135   
136    /**
137    * Load alignment from (file, protocol) and wait till loaded
138    *
139    * @param file
140    * @param sourceType
141    * @return alignFrame constructed from file contents
142    */
 
143  106 toggle public AlignFrame LoadFileWaitTillLoaded(String file,
144    DataSourceType sourceType)
145    {
146  106 return LoadFileWaitTillLoaded(file, sourceType, null);
147    }
148   
149    /**
150    * Load alignment from (file, protocol) of type format and wait till loaded
151    *
152    * @param file
153    * @param sourceType
154    * @param format
155    * @return alignFrame constructed from file contents
156    */
 
157  125 toggle public AlignFrame LoadFileWaitTillLoaded(String file,
158    DataSourceType sourceType, FileFormatI format)
159    {
160  125 this.file = file;
161  125 this.protocol = sourceType;
162  125 this.format = format;
163  125 return _LoadFileWaitTillLoaded();
164    }
165   
166    /**
167    * Load alignment from (file, protocol) of type format and wait till loaded
168    *
169    * @param file
170    * @param sourceType
171    * @param format
172    * @return alignFrame constructed from file contents
173    */
 
174  0 toggle public AlignFrame LoadFileWaitTillLoaded(File file,
175    DataSourceType sourceType, FileFormatI format)
176    {
177  0 this.selectedFile = file;
178  0 this.file = file.getPath();
179  0 this.protocol = sourceType;
180  0 this.format = format;
181  0 return _LoadFileWaitTillLoaded();
182    }
183   
184    /**
185    * Load alignment from FileParse source of type format and wait till loaded
186    *
187    * @param source
188    * @param format
189    * @return alignFrame constructed from file contents
190    */
 
191  0 toggle public AlignFrame LoadFileWaitTillLoaded(AlignmentFileReaderI source,
192    FileFormatI format)
193    {
194  0 this.source = source;
195   
196  0 file = source.getInFile();
197  0 protocol = source.getDataSourceType();
198  0 this.format = format;
199  0 return _LoadFileWaitTillLoaded();
200    }
201   
202    /**
203    * runs the 'run' method (in this thread), then return the alignFrame that's
204    * (hopefully) been read
205    *
206    * @return
207    */
 
208  125 toggle protected AlignFrame _LoadFileWaitTillLoaded()
209    {
210  125 this.run();
211   
212  125 return alignFrame;
213    }
214   
 
215  125 toggle public void updateRecentlyOpened()
216    {
217  125 Vector<String> recent = new Vector<>();
218  125 if (protocol == DataSourceType.PASTE)
219    {
220    // do nothing if the file was pasted in as text... there is no filename to
221    // refer to it as.
222  38 return;
223    }
224  87 if (file != null
225    && file.indexOf(System.getProperty("java.io.tmpdir")) > -1)
226    {
227    // ignore files loaded from the system's temporary directory
228  12 return;
229    }
230  75 String type = protocol == DataSourceType.FILE ? "RECENT_FILE"
231    : "RECENT_URL";
232   
233  75 String historyItems = Cache.getProperty(type);
234   
235  75 StringTokenizer st;
236   
237  75 if (historyItems != null)
238    {
239  75 st = new StringTokenizer(historyItems, "\t");
240   
241  326 while (st.hasMoreTokens())
242    {
243  251 recent.addElement(st.nextToken().trim());
244    }
245    }
246   
247  75 if (recent.contains(file))
248    {
249  59 recent.remove(file);
250    }
251   
252  75 StringBuffer newHistory = new StringBuffer(file);
253  267 for (int i = 0; i < recent.size() && i < 10; i++)
254    {
255  192 newHistory.append("\t");
256  192 newHistory.append(recent.elementAt(i));
257    }
258   
259  75 Cache.setProperty(type, newHistory.toString());
260   
261  75 if (protocol == DataSourceType.FILE)
262    {
263  75 Cache.setProperty("DEFAULT_FILE_FORMAT", format.getName());
264    }
265    }
266   
 
267  126 toggle @Override
268    public void run()
269    {
270  126 String title = protocol == DataSourceType.PASTE
271    ? "Copied From Clipboard"
272    : file;
273  126 Runtime rt = Runtime.getRuntime();
274  126 try
275    {
276  126 if (Desktop.instance != null)
277    {
278  99 Desktop.instance.startLoading(file);
279    }
280  126 if (format == null)
281    {
282    // just in case the caller didn't identify the file for us
283  106 if (source != null)
284    {
285  0 format = new IdentifyFile().identify(source, false);
286    // identify stream and rewind rather than close
287    }
288  106 else if (selectedFile != null) {
289  0 format = new IdentifyFile().identify(selectedFile, protocol);
290    }
291    else
292    {
293  106 format = new IdentifyFile().identify(file, protocol);
294    }
295   
296    }
297   
298  126 if (format == null)
299    {
300  0 Desktop.instance.stopLoading();
301  0 System.err.println("The input file \"" + file
302    + "\" has null or unidentifiable data content!");
303  0 if (!Jalview.isHeadlessMode())
304    {
305  0 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
306    MessageManager.getString("label.couldnt_read_data")
307    + " in " + file + "\n"
308    + AppletFormatAdapter.getSupportedFormats(),
309    MessageManager.getString("label.couldnt_read_data"),
310    JvOptionPane.WARNING_MESSAGE);
311    }
312  0 return;
313    }
314    // TODO: cache any stream datasources as a temporary file (eg. PDBs
315    // retrieved via URL)
316  126 if (Desktop.desktop != null && Desktop.desktop.isShowMemoryUsage())
317    {
318  0 System.gc();
319  0 memused = (rt.maxMemory() - rt.totalMemory() + rt.freeMemory()); // free
320    // memory
321    // before
322    // load
323    }
324  126 loadtime = -System.currentTimeMillis();
325  126 AlignmentI al = null;
326   
327  126 if (FileFormat.Jalview.equals(format))
328    {
329  21 if (source != null)
330    {
331    // Tell the user (developer?) that this is going to cause a problem
332  0 System.err.println(
333    "IMPLEMENTATION ERROR: Cannot read consecutive Jalview XML projects from a stream.");
334    // We read the data anyway - it might make sense.
335    }
336    // BH 2018 switch to File object here instead of filename
337  21 alignFrame = new Jalview2XML(raiseGUI).loadJalviewAlign(selectedFile == null ? file : selectedFile);
338    }
339    else
340    {
341  105 String error = AppletFormatAdapter.getSupportedFormats();
342  105 try
343    {
344  105 if (source != null)
345    {
346    // read from the provided source
347  0 al = new FormatAdapter().readFromFile(source, format);
348    }
349    else
350    {
351   
352    // open a new source and read from it
353  105 FormatAdapter fa = new FormatAdapter();
354  105 boolean downloadStructureFile = format.isStructureFile()
355    && protocol.equals(DataSourceType.URL);
356  105 if (downloadStructureFile)
357    {
358  0 String structExt = format.getExtensions().split(",")[0];
359  0 String urlLeafName = file.substring(
360    file.lastIndexOf(
361    System.getProperty("file.separator")),
362    file.lastIndexOf("."));
363  0 String tempStructureFileStr = createNamedJvTempFile(
364    urlLeafName, structExt);
365   
366    // BH - switching to File object here so as to hold
367    // ._bytes array directly
368  0 File tempFile = new File(tempStructureFileStr);
369  0 UrlDownloadClient.download(file, tempFile);
370   
371  0 al = fa.readFile(tempFile, DataSourceType.FILE,
372    format);
373  0 source = fa.getAlignFile();
374    }
375    else
376    {
377  105 if (selectedFile == null) {
378  105 al = fa.readFile(file, protocol, format);
379   
380    } else {
381  0 al = fa.readFile(selectedFile, protocol, format);
382    }
383  105 source = fa.getAlignFile(); // keep reference for later if
384   
385    // necessary.
386    }
387    }
388    } catch (java.io.IOException ex)
389    {
390  0 error = ex.getMessage();
391    }
392   
393  105 if ((al != null) && (al.getHeight() > 0) && al.hasValidSequence())
394    {
395    // construct and register dataset sequences
396  105 for (SequenceI sq : al.getSequences())
397    {
398  996 while (sq.getDatasetSequence() != null)
399    {
400  2 sq = sq.getDatasetSequence();
401    }
402  994 if (sq.getAllPDBEntries() != null)
403    {
404  994 for (PDBEntry pdbe : sq.getAllPDBEntries())
405    {
406    // register PDB entries with desktop's structure selection
407    // manager
408  36 StructureSelectionManager
409    .getStructureSelectionManager(Desktop.instance)
410    .registerPDBEntry(pdbe);
411    }
412    }
413    }
414   
415  105 FeatureSettingsModelI proxyColourScheme = source
416    .getFeatureColourScheme();
417  105 if (viewport != null)
418    {
419  1 if (proxyColourScheme != null)
420    {
421  1 viewport.applyFeaturesStyle(proxyColourScheme);
422    }
423    // append to existing alignment
424  1 viewport.addAlignment(al, title);
425    }
426    else
427    {
428    // otherwise construct the alignFrame
429   
430  104 if (source instanceof ComplexAlignFile)
431    {
432  0 HiddenColumns colSel = ((ComplexAlignFile) source)
433    .getHiddenColumns();
434  0 SequenceI[] hiddenSeqs = ((ComplexAlignFile) source)
435    .getHiddenSequences();
436  0 String colourSchemeName = ((ComplexAlignFile) source)
437    .getGlobalColourScheme();
438  0 FeaturesDisplayedI fd = ((ComplexAlignFile) source)
439    .getDisplayedFeatures();
440  0 alignFrame = new AlignFrame(al, hiddenSeqs, colSel,
441    AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
442  0 alignFrame.getViewport().setFeaturesDisplayed(fd);
443  0 alignFrame.getViewport().setShowSequenceFeatures(
444    ((ComplexAlignFile) source).isShowSeqFeatures());
445  0 ColourSchemeI cs = ColourSchemeMapper
446    .getJalviewColourScheme(colourSchemeName, al);
447  0 if (cs != null)
448    {
449  0 alignFrame.changeColour(cs);
450    }
451    }
452    else
453    {
454  104 alignFrame = new AlignFrame(al, AlignFrame.DEFAULT_WIDTH,
455    AlignFrame.DEFAULT_HEIGHT);
456  103 if (source instanceof FeaturesSourceI)
457    {
458  1 alignFrame.getViewport().setShowSequenceFeatures(true);
459    }
460    }
461    // add metadata and update ui
462  103 if (!(protocol == DataSourceType.PASTE))
463    {
464  65 alignFrame.setFileName(file, format);
465  65 alignFrame.setFileObject(selectedFile); // BH 2018 SwingJS
466    }
467  103 if (proxyColourScheme != null)
468    {
469  12 alignFrame.getViewport()
470    .applyFeaturesStyle(proxyColourScheme);
471    }
472  103 alignFrame.setStatus(MessageManager.formatMessage(
473    "label.successfully_loaded_file", new String[]
474    { title }));
475   
476  103 if (raiseGUI)
477    {
478    // add the window to the GUI
479    // note - this actually should happen regardless of raiseGUI
480    // status in Jalview 3
481    // TODO: define 'virtual desktop' for benefit of headless scripts
482    // that perform queries to find the 'current working alignment'
483  69 Desktop.addInternalFrame(alignFrame, title,
484    AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
485    }
486   
487  103 try
488    {
489  103 alignFrame.setMaximum(jalview.bin.Cache
490    .getDefault("SHOW_FULLSCREEN", false));
491    } catch (java.beans.PropertyVetoException ex)
492    {
493    }
494    }
495    }
496    else
497    {
498  0 if (Desktop.instance != null)
499    {
500  0 Desktop.instance.stopLoading();
501    }
502   
503  0 final String errorMessage = MessageManager.getString(
504    "label.couldnt_load_file") + " " + title + "\n" + error;
505    // TODO: refactor FileLoader to be independent of Desktop / Applet GUI
506    // bits ?
507  0 if (raiseGUI && Desktop.desktop != null)
508    {
509  0 javax.swing.SwingUtilities.invokeLater(new Runnable()
510    {
 
511  0 toggle @Override
512    public void run()
513    {
514  0 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
515    errorMessage,
516    MessageManager
517    .getString("label.error_loading_file"),
518    JvOptionPane.WARNING_MESSAGE);
519    }
520    });
521    }
522    else
523    {
524  0 System.err.println(errorMessage);
525    }
526    }
527    }
528   
529  125 updateRecentlyOpened();
530   
531    } catch (Exception er)
532    {
533  1 System.err.println("Exception whilst opening file '" + file);
534  1 er.printStackTrace();
535  1 if (raiseGUI)
536    {
537  1 javax.swing.SwingUtilities.invokeLater(new Runnable()
538    {
 
539  1 toggle @Override
540    public void run()
541    {
542  1 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
543    MessageManager.formatMessage(
544    "label.problems_opening_file", new String[]
545    { file }),
546    MessageManager.getString("label.file_open_error"),
547    JvOptionPane.WARNING_MESSAGE);
548    }
549    });
550    }
551  1 alignFrame = null;
552    } catch (OutOfMemoryError er)
553    {
554   
555  0 er.printStackTrace();
556  0 alignFrame = null;
557  0 if (raiseGUI)
558    {
559  0 javax.swing.SwingUtilities.invokeLater(new Runnable()
560    {
 
561  0 toggle @Override
562    public void run()
563    {
564  0 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
565    MessageManager.formatMessage(
566    "warn.out_of_memory_loading_file", new String[]
567    { file }),
568    MessageManager.getString("label.out_of_memory"),
569    JvOptionPane.WARNING_MESSAGE);
570    }
571    });
572    }
573  0 System.err.println("Out of memory loading file " + file + "!!");
574   
575    }
576  126 loadtime += System.currentTimeMillis();
577    // TODO: Estimate percentage of memory used by a newly loaded alignment -
578    // warn if more memory will be needed to work with it
579    // System.gc();
580  126 memused = memused
581    - (rt.maxMemory() - rt.totalMemory() + rt.freeMemory()); // difference
582    // in free
583    // memory
584    // after
585    // load
586  126 if (Desktop.desktop != null && Desktop.desktop.isShowMemoryUsage())
587    {
588  0 if (alignFrame != null)
589    {
590  0 AlignmentI al = alignFrame.getViewport().getAlignment();
591   
592  0 System.out.println("Loaded '" + title + "' in "
593    + (loadtime / 1000.0) + "s, took an additional "
594    + (1.0 * memused / (1024.0 * 1024.0)) + " MB ("
595    + al.getHeight() + " seqs by " + al.getWidth() + " cols)");
596    }
597    else
598    {
599    // report that we didn't load anything probably due to an out of memory
600    // error
601  0 System.out.println("Failed to load '" + title + "' in "
602    + (loadtime / 1000.0) + "s, took an additional "
603    + (1.0 * memused / (1024.0 * 1024.0))
604    + " MB (alignment is null)");
605    }
606    }
607    // remove the visual delay indicator
608  126 if (Desktop.instance != null)
609    {
610  99 Desktop.instance.stopLoading();
611    }
612   
613    }
614   
615    /**
616    * This method creates the file -
617    * {tmpdir}/jalview/{current_timestamp}/fileName.exetnsion using the supplied
618    * file name and extension
619    *
620    * @param fileName
621    * the name of the temp file to be created
622    * @param extension
623    * the extension of the temp file to be created
624    * @return
625    */
 
626  0 toggle private static String createNamedJvTempFile(String fileName,
627    String extension) throws IOException
628    {
629  0 String seprator = System.getProperty("file.separator");
630  0 String jvTempDir = System.getProperty("java.io.tmpdir") + "jalview"
631    + seprator + System.currentTimeMillis();
632  0 File tempStructFile = new File(
633    jvTempDir + seprator + fileName + "." + extension);
634  0 tempStructFile.mkdirs();
635  0 return tempStructFile.toString();
636    }
637   
638    }