Clover icon

Coverage Report

  1. Project Clover database Thu Dec 4 2025 14:43:25 GMT
  2. Package jalview.io

File FileLoader.java

 

Coverage histogram

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

Code metrics

100
206
22
1
766
543
90
0.44
9.36
22
4.09

Classes

Class Line # Actions
FileLoader 56 206 90
0.6432926764.3%
 

Contributing tests

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