Clover icon

jalviewX

  1. Project Clover database Wed Oct 31 2018 15:13:58 GMT
  2. Package jalview.io

File AppletFormatAdapter.java

 

Coverage histogram

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

Code metrics

96
204
18
1
690
496
84
0.41
11.33
18
4.67

Classes

Class Line # Actions
AppletFormatAdapter 48 204 84 229
0.279874228%
 

Contributing tests

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