Clover icon

Coverage Report

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

File AppletFormatAdapter.java

 

Coverage histogram

../../img/srcFileCovDistChart3.png
47% of files have more coverage

Code metrics

96
204
18
1
699
501
84
0.41
11.33
18
4.67

Classes

Class Line # Actions
AppletFormatAdapter 49 204 84
0.289308228.9%
 

Contributing tests

This file is covered by 129 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 jalview.api.AlignExportSettingsI;
24    import jalview.api.AlignmentViewPanel;
25    import jalview.datamodel.Alignment;
26    import jalview.datamodel.AlignmentAnnotation;
27    import jalview.datamodel.AlignmentI;
28    import jalview.datamodel.AlignmentView;
29    import jalview.datamodel.PDBEntry.Type;
30    import jalview.datamodel.SequenceI;
31    import jalview.ext.jmol.JmolParser;
32    import jalview.structure.StructureImportSettings;
33    import jalview.util.Platform;
34   
35    import java.io.File;
36    import java.io.IOException;
37    import java.io.InputStream;
38    import java.util.List;
39   
40    /**
41    * A low level class for alignment and feature IO with alignment formatting
42    * methods used by both applet and application for generating flat alignment
43    * files. It also holds the lists of magic format names that the applet and
44    * application will allow the user to read or write files with.
45    *
46    * @author $author$
47    * @version $Revision$
48    */
 
49    public class AppletFormatAdapter
50    {
51    private AlignmentViewPanel viewpanel;
52   
53    /**
54    * add jalview-derived non-secondary structure annotation from PDB structure
55    */
56    boolean annotFromStructure = false;
57   
58    /**
59    * add secondary structure from PDB data with built-in algorithms
60    */
61    boolean localSecondaryStruct = false;
62   
63    /**
64    * process PDB data with web services
65    */
66    boolean serviceSecondaryStruct = false;
67   
68    private AlignmentFileReaderI alignFile = null;
69   
70    String inFile;
71   
72    /**
73    * character used to write newlines
74    */
75    protected String newline = System.getProperty("line.separator");
76   
77    private AlignExportSettingsI exportSettings;
78   
79    private File selectedFile;
80   
81    public static String INVALID_CHARACTERS = "Contains invalid characters";
82   
83    /**
84    * Returns an error message with a list of supported readable file formats
85    *
86    * @return
87    */
 
88  105 toggle public static String getSupportedFormats()
89    {
90  105 return "Formats currently supported are\n"
91    + prettyPrint(FileFormats.getInstance().getReadableFormats());
92    }
93   
 
94  323 toggle public AppletFormatAdapter()
95    {
96    }
97   
 
98  2 toggle public AppletFormatAdapter(AlignmentViewPanel viewpanel)
99    {
100  2 this.viewpanel = viewpanel;
101    }
102   
 
103  46 toggle public AppletFormatAdapter(AlignmentViewPanel alignPanel,
104    AlignExportSettingsI settings)
105    {
106  46 viewpanel = alignPanel;
107  46 exportSettings = settings;
108    }
109   
110    /**
111    * Formats a grammatically correct(ish) list consisting of the given objects
112    *
113    * @param things
114    * @return
115    */
 
116  105 toggle public static String prettyPrint(List<? extends Object> things)
117    {
118  105 StringBuffer list = new StringBuffer();
119  1785 for (int i = 0, iSize = things.size() - 1; i < iSize; i++)
120    {
121  1680 list.append(things.get(i).toString());
122  1680 list.append(", ");
123    }
124    // could i18n 'and' here
125  105 list.append(" and " + things.get(things.size() - 1).toString() + ".");
126  105 return list.toString();
127    }
128   
 
129  0 toggle public void setNewlineString(String nl)
130    {
131  0 newline = nl;
132    }
133   
 
134  0 toggle public String getNewlineString()
135    {
136  0 return newline;
137    }
138   
139    /**
140    * Constructs the correct filetype parser for a characterised datasource
141    *
142    * @param inFile
143    * data/data location
144    * @param sourceType
145    * type of datasource
146    * @param fileFormat
147    *
148    * @return
149    */
 
150  281 toggle public AlignmentI readFile(String file, DataSourceType sourceType,
151    FileFormatI fileFormat) throws IOException
152    {
153  281 return readFile(null, file, sourceType, fileFormat);
154    }
155   
 
156  281 toggle public AlignmentI readFile(File selectedFile, String file, DataSourceType sourceType,
157    FileFormatI fileFormat) throws IOException
158    {
159   
160  281 this.selectedFile = selectedFile;
161  281 if (selectedFile != null)
162    {
163  0 this.inFile = selectedFile.getPath();
164    }
165  281 this.inFile = file;
166  281 try
167    {
168  281 if (fileFormat.isStructureFile())
169    {
170  14 String structureParser = StructureImportSettings
171    .getDefaultPDBFileParser();
172  14 boolean isParseWithJMOL = structureParser.equalsIgnoreCase(
173    StructureImportSettings.StructureParser.JMOL_PARSER
174    .toString());
175  14 StructureImportSettings.addSettings(annotFromStructure,
176    localSecondaryStruct, serviceSecondaryStruct);
177  14 if (isParseWithJMOL)
178    {
179    // needs a File option
180  11 alignFile = new JmolParser(selectedFile == null ? inFile : selectedFile, sourceType);
181    }
182    else
183    {
184    // todo is mc_view parsing obsolete yet? JAL-2120
185  3 StructureImportSettings.setShowSeqFeatures(true);
186  3 alignFile = new mc_view.PDBfile(annotFromStructure,
187    localSecondaryStruct, serviceSecondaryStruct, inFile,
188    sourceType);
189    }
190  14 ((StructureFile) alignFile).setDbRefType(
191  14 FileFormat.PDB.equals(fileFormat) ? Type.PDB : Type.MMCIF);
192    }
193  267 else if (selectedFile != null) {
194  0 alignFile = fileFormat.getReader(new FileParse(selectedFile, sourceType));
195    } else
196    {
197    // alignFile = fileFormat.getAlignmentFile(inFile, sourceType);
198  267 alignFile = fileFormat.getReader(new FileParse(inFile, sourceType));
199    }
200  281 return buildAlignmentFromFile();
201    } catch (Exception e)
202    {
203  0 e.printStackTrace();
204  0 System.err.println("Failed to read alignment using the '" + fileFormat
205    + "' reader.\n" + e);
206   
207  0 if (e.getMessage() != null
208    && e.getMessage().startsWith(INVALID_CHARACTERS))
209    {
210  0 throw new IOException(e.getMessage());
211    }
212   
213    // Finally test if the user has pasted just the sequence, no id
214  0 if (sourceType == DataSourceType.PASTE)
215    {
216  0 try
217    {
218    // Possible sequence is just residues with no label
219  0 alignFile = new FastaFile(">UNKNOWN\n" + inFile,
220    DataSourceType.PASTE);
221  0 return buildAlignmentFromFile();
222   
223    } catch (Exception ex)
224    {
225  0 if (ex.toString().startsWith(INVALID_CHARACTERS))
226    {
227  0 throw new IOException(e.getMessage());
228    }
229   
230  0 ex.printStackTrace();
231    }
232    }
233  0 if (FileFormat.Html.equals(fileFormat))
234    {
235  0 throw new IOException(e.getMessage());
236    }
237    }
238  0 throw new FileFormatException(getSupportedFormats());
239    }
240   
241    /**
242    * Constructs the correct filetype parser for an already open datasource
243    *
244    * @param source
245    * an existing datasource
246    * @param format
247    * File format of data that will be provided by datasource
248    *
249    * @return
250    */
 
251  0 toggle public AlignmentI readFromFile(FileParse source, FileFormatI format)
252    throws IOException
253    {
254  0 this.inFile = source.getInFile();
255  0 DataSourceType type = source.dataSourceType;
256  0 try
257    {
258  0 if (FileFormat.PDB.equals(format) || FileFormat.MMCif.equals(format))
259    {
260    // TODO obtain config value from preference settings
261  0 boolean isParseWithJMOL = false;
262  0 if (isParseWithJMOL)
263    {
264  0 StructureImportSettings.addSettings(annotFromStructure,
265    localSecondaryStruct, serviceSecondaryStruct);
266  0 alignFile = new JmolParser(source);
267    }
268    else
269    {
270  0 StructureImportSettings.setShowSeqFeatures(true);
271  0 alignFile = new mc_view.PDBfile(annotFromStructure,
272    localSecondaryStruct, serviceSecondaryStruct, source);
273    }
274  0 ((StructureFile) alignFile).setDbRefType(Type.PDB);
275    }
276    else
277    {
278  0 alignFile = format.getReader(source);
279    }
280   
281  0 return buildAlignmentFromFile();
282   
283    } catch (Exception e)
284    {
285  0 e.printStackTrace();
286  0 System.err.println("Failed to read alignment using the '" + format
287    + "' reader.\n" + e);
288   
289  0 if (e.getMessage() != null
290    && e.getMessage().startsWith(INVALID_CHARACTERS))
291    {
292  0 throw new FileFormatException(e.getMessage());
293    }
294   
295    // Finally test if the user has pasted just the sequence, no id
296  0 if (type == DataSourceType.PASTE)
297    {
298  0 try
299    {
300    // Possible sequence is just residues with no label
301  0 alignFile = new FastaFile(">UNKNOWN\n" + inFile,
302    DataSourceType.PASTE);
303  0 return buildAlignmentFromFile();
304   
305    } catch (Exception ex)
306    {
307  0 if (ex.toString().startsWith(INVALID_CHARACTERS))
308    {
309  0 throw new IOException(e.getMessage());
310    }
311   
312  0 ex.printStackTrace();
313    }
314    }
315   
316    // If we get to this stage, the format was not supported
317  0 throw new FileFormatException(getSupportedFormats());
318    }
319    }
320   
321    /**
322    * boilerplate method to handle data from an AlignFile and construct a new
323    * alignment or import to an existing alignment
324    *
325    * @return AlignmentI instance ready to pass to a UI constructor
326    */
 
327  281 toggle private AlignmentI buildAlignmentFromFile()
328    {
329    // Standard boilerplate for creating alignment from parser
330    // alignFile.configureForView(viewpanel);
331   
332  281 AlignmentI al = new Alignment(alignFile.getSeqsAsArray());
333   
334  281 alignFile.addAnnotations(al);
335   
336  281 alignFile.addGroups(al);
337   
338  281 return al;
339    }
340   
341    /**
342    * create an alignment flatfile from a Jalview alignment view
343    *
344    * @param format
345    * @param jvsuffix
346    * @param av
347    * @param selectedOnly
348    * @return flatfile in a string
349    */
 
350  1 toggle public String formatSequences(FileFormatI format, boolean jvsuffix,
351    AlignmentViewPanel ap, boolean selectedOnly)
352    {
353   
354  1 AlignmentView selvew = ap.getAlignViewport()
355    .getAlignmentView(selectedOnly, false);
356  1 AlignmentI aselview = selvew
357    .getVisibleAlignment(ap.getAlignViewport().getGapCharacter());
358  1 List<AlignmentAnnotation> ala = (ap.getAlignViewport()
359    .getVisibleAlignmentAnnotation(selectedOnly));
360  1 if (ala != null)
361    {
362  1 for (AlignmentAnnotation aa : ala)
363    {
364  4 aselview.addAnnotation(aa);
365    }
366    }
367  1 viewpanel = ap;
368  1 return formatSequences(format, aselview, jvsuffix);
369    }
370   
371    /**
372    * Construct an output class for an alignment in a particular filetype TODO:
373    * allow caller to detect errors and warnings encountered when generating
374    * output
375    *
376    * @param format
377    * string name of alignment format
378    * @param alignment
379    * the alignment to be written out
380    * @param jvsuffix
381    * passed to AlnFile class controls whether /START-END is added to
382    * sequence names
383    *
384    * @return alignment flat file contents
385    */
 
386  96 toggle public String formatSequences(FileFormatI format, AlignmentI alignment,
387    boolean jvsuffix)
388    {
389  96 try
390    {
391  96 AlignmentFileWriterI afile = format.getWriter(alignment);
392   
393  96 afile.setNewlineString(newline);
394  96 afile.setExportSettings(exportSettings);
395  96 afile.configureForView(viewpanel);
396   
397    // check whether we were given a specific alignment to export, rather than
398    // the one in the viewpanel
399  96 SequenceI[] seqs = null;
400  96 if (viewpanel == null || viewpanel.getAlignment() == null
401    || viewpanel.getAlignment() != alignment)
402    {
403  49 seqs = alignment.getSequencesArray();
404    }
405    else
406    {
407  47 seqs = viewpanel.getAlignment().getSequencesArray();
408    }
409   
410  96 String afileresp = afile.print(seqs, jvsuffix);
411  96 if (afile.hasWarningMessage())
412    {
413  0 System.err.println("Warning raised when writing as " + format
414    + " : " + afile.getWarningMessage());
415    }
416  96 return afileresp;
417    } catch (Exception e)
418    {
419  0 System.err.println("Failed to write alignment as a '"
420    + format.getName() + "' file\n");
421  0 e.printStackTrace();
422    }
423   
424  0 return null;
425    }
426   
427   
428    /**
429    * Determines the protocol (i.e DataSourceType.{FILE|PASTE|URL}) for the input
430    * data
431    *
432    * BH 2018 allows File or String, and can return RELATIVE_URL
433    *
434    * @param dataObject File or String
435    * @return the protocol for the input data
436    */
 
437  78 toggle public static DataSourceType checkProtocol(Object dataObject)
438    {
439  78 if(dataObject instanceof File)
440    {
441  0 return DataSourceType.FILE;
442    }
443   
444  78 String data = dataObject.toString();
445  78 DataSourceType protocol = DataSourceType.PASTE;
446  78 String ft = data.toLowerCase().trim();
447  78 if (ft.indexOf("http:") == 0 || ft.indexOf("https:") == 0
448    || ft.indexOf("file:") == 0)
449    {
450  0 protocol = DataSourceType.URL;
451    }
452  78 else if (Platform.isJS())
453    {
454  0 protocol = DataSourceType.RELATIVE_URL;
455    }
456  78 else if (new File(data).exists())
457    {
458  66 protocol = DataSourceType.FILE;
459    }
460  78 return protocol;
461    }
462   
463    /**
464    * @param args
465    * @j2sIgnore
466    */
 
467  0 toggle public static void main(String[] args)
468    {
469  0 int i = 0;
470  0 while (i < args.length)
471    {
472  0 File f = new File(args[i]);
473  0 if (f.exists())
474    {
475  0 try
476    {
477  0 System.out.println("Reading file: " + f);
478  0 AppletFormatAdapter afa = new AppletFormatAdapter();
479  0 Runtime r = Runtime.getRuntime();
480  0 System.gc();
481  0 long memf = -r.totalMemory() + r.freeMemory();
482  0 long t1 = -System.currentTimeMillis();
483  0 AlignmentI al = afa.readFile(args[i], DataSourceType.FILE,
484    new IdentifyFile().identify(args[i],
485    DataSourceType.FILE));
486  0 t1 += System.currentTimeMillis();
487  0 System.gc();
488  0 memf += r.totalMemory() - r.freeMemory();
489  0 if (al != null)
490    {
491  0 System.out.println("Alignment contains " + al.getHeight()
492    + " sequences and " + al.getWidth() + " columns.");
493  0 try
494    {
495  0 System.out.println(new AppletFormatAdapter()
496    .formatSequences(FileFormat.Fasta, al, true));
497    } catch (Exception e)
498    {
499  0 System.err.println(
500    "Couln't format the alignment for output as a FASTA file.");
501  0 e.printStackTrace(System.err);
502    }
503    }
504    else
505    {
506  0 System.out.println("Couldn't read alignment");
507    }
508  0 System.out.println("Read took " + (t1 / 1000.0) + " seconds.");
509  0 System.out.println(
510    "Difference between free memory now and before is "
511    + (memf / (1024.0 * 1024.0) * 1.0) + " MB");
512    } catch (Exception e)
513    {
514  0 System.err.println("Exception when dealing with " + i
515    + "'th argument: " + args[i] + "\n" + e);
516    }
517    }
518    else
519    {
520  0 System.err.println("Ignoring argument '" + args[i] + "' (" + i
521    + "'th)- not a readable file.");
522    }
523  0 i++;
524    }
525    }
526   
527    /**
528    * try to discover how to access the given file as a valid datasource that
529    * will be identified as the given type.
530    *
531    * @param file
532    * @param format
533    * @return protocol that yields the data parsable as the given type
534    */
 
535  0 toggle public static DataSourceType resolveProtocol(String file,
536    FileFormatI format)
537    {
538  0 return resolveProtocol(file, format, false);
539    }
540   
 
541  0 toggle public static DataSourceType resolveProtocol(String file,
542    FileFormatI format, boolean debug)
543    {
544    // TODO: test thoroughly!
545  0 DataSourceType protocol = null;
546  0 if (debug)
547    {
548  0 System.out.println("resolving datasource started with:\n>>file\n"
549    + file + ">>endfile");
550    }
551   
552    // This might throw a security exception in certain browsers
553    // Netscape Communicator for instance.
554  0 try
555    {
556  0 boolean rtn = false;
557  0 InputStream is = System.getSecurityManager().getClass()
558    .getResourceAsStream("/" + file);
559  0 if (is != null)
560    {
561  0 rtn = true;
562  0 is.close();
563    }
564  0 if (debug)
565    {
566  0 System.err.println("Resource '" + file + "' was "
567  0 + (rtn ? "" : "not") + " located by classloader.");
568    }
569  0 if (rtn)
570    {
571  0 protocol = DataSourceType.CLASSLOADER;
572    }
573   
574    } catch (Exception ex)
575    {
576  0 System.err
577    .println("Exception checking resources: " + file + " " + ex);
578    }
579   
580  0 if (file.indexOf("://") > -1)
581    {
582  0 protocol = DataSourceType.URL;
583    }
584    else
585    {
586    // skipping codebase prepend check.
587  0 protocol = DataSourceType.FILE;
588    }
589  0 FileParse fp = null;
590  0 try
591    {
592  0 if (debug)
593    {
594  0 System.out.println(
595    "Trying to get contents of resource as " + protocol + ":");
596    }
597  0 fp = new FileParse(file, protocol);
598  0 if (!fp.isValid())
599    {
600  0 fp = null;
601    }
602    else
603    {
604  0 if (debug)
605    {
606  0 System.out.println("Successful.");
607    }
608    }
609    } catch (Exception e)
610    {
611  0 if (debug)
612    {
613  0 System.err.println("Exception when accessing content: " + e);
614    }
615  0 fp = null;
616    }
617  0 if (fp == null)
618    {
619  0 if (debug)
620    {
621  0 System.out.println("Accessing as paste.");
622    }
623  0 protocol = DataSourceType.PASTE;
624  0 fp = null;
625  0 try
626    {
627  0 fp = new FileParse(file, protocol);
628  0 if (!fp.isValid())
629    {
630  0 fp = null;
631    }
632    } catch (Exception e)
633    {
634  0 System.err.println("Failed to access content as paste!");
635  0 e.printStackTrace();
636  0 fp = null;
637    }
638    }
639  0 if (fp == null)
640    {
641  0 return null;
642    }
643  0 if (format == null)
644    {
645  0 return protocol;
646    }
647    else
648    {
649  0 try
650    {
651  0 FileFormatI idformat = new IdentifyFile().identify(file, protocol);
652  0 if (idformat == null)
653    {
654  0 if (debug)
655    {
656  0 System.out.println("Format not identified. Inaccessible file.");
657    }
658  0 return null;
659    }
660  0 if (debug)
661    {
662  0 System.out.println("Format identified as " + idformat
663    + "and expected as " + format);
664    }
665  0 if (idformat.equals(format))
666    {
667  0 if (debug)
668    {
669  0 System.out.println("Protocol identified as " + protocol);
670    }
671  0 return protocol;
672    }
673    else
674    {
675  0 if (debug)
676    {
677  0 System.out
678    .println("File deemed not accessible via " + protocol);
679    }
680  0 fp.close();
681  0 return null;
682    }
683    } catch (Exception e)
684    {
685  0 if (debug)
686    {
687  0 System.err.println("File deemed not accessible via " + protocol);
688  0 e.printStackTrace();
689    }
690    }
691    }
692  0 return null;
693    }
694   
 
695  109 toggle public AlignmentFileReaderI getAlignFile()
696    {
697  109 return alignFile;
698    }
699    }