552f00edc24cbc8fea60631a5ce93f6369dc71e0
[jalview.git] / src / jalview / io / AppletFormatAdapter.java
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.AlignExportSettingI;
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.ext.jmol.JmolParser;
31 import jalview.structure.StructureImportSettings;
32 import jalview.util.MessageManager;
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   public static String FILE = "File";
53
54   public static String URL = "URL";
55
56   public static String PASTE = "Paste";
57
58   public static String CLASSLOADER = "ClassLoader";
59
60   /**
61    * add jalview-derived non-secondary structure annotation from PDB structure
62    */
63   boolean annotFromStructure = false;
64
65   /**
66    * add secondary structure from PDB data with built-in algorithms
67    */
68   boolean localSecondaryStruct = false;
69
70   /**
71    * process PDB data with web services
72    */
73   boolean serviceSecondaryStruct = false;
74
75   private AlignFile alignFile = null;
76
77   String inFile;
78
79   /**
80    * character used to write newlines
81    */
82   protected String newline = System.getProperty("line.separator");
83
84   private AlignExportSettingI exportSettings;
85
86   /**
87    * List of valid format strings used in the isValidFormat method
88    */
89   public static final String[] READABLE_FORMATS = new String[] { "BLC",
90       "CLUSTAL", "FASTA", "MSF", "PileUp", "PIR", "PFAM", "STH", "PDB",
91       "JnetFile", "RNAML", PhylipFile.FILE_DESC, JSONFile.FILE_DESC,
92       IdentifyFile.FeaturesFile, "HTML", "mmCIF" };
93
94   /**
95    * List of readable format file extensions by application in order
96    * corresponding to READABLE_FNAMES
97    */
98   public static final String[] READABLE_EXTENSIONS = new String[] {
99       "fa, fasta, mfa, fastq", "aln", "pfam", "msf", "pir", "blc", "amsa",
100       "sto,stk", "xml,rnaml", PhylipFile.FILE_EXT, JSONFile.FILE_EXT,
101       ".gff2,gff3", "jar,jvp", HtmlFile.FILE_EXT, "cif" };
102
103   /**
104    * List of readable formats by application in order corresponding to
105    * READABLE_EXTENSIONS
106    */
107   public static final String[] READABLE_FNAMES = new String[] { "Fasta",
108       "Clustal", "PFAM", "MSF", "PIR", "BLC", "AMSA", "Stockholm", "RNAML",
109       PhylipFile.FILE_DESC, JSONFile.FILE_DESC, IdentifyFile.FeaturesFile,
110       "Jalview", HtmlFile.FILE_DESC, "mmCIF" };
111
112   /**
113    * List of valid format strings for use by callers of the formatSequences
114    * method
115    */
116   public static final String[] WRITEABLE_FORMATS = new String[] { "BLC",
117       "CLUSTAL", "FASTA", "MSF", "PileUp", "PIR", "PFAM", "AMSA", "STH",
118       PhylipFile.FILE_DESC, JSONFile.FILE_DESC };
119
120   /**
121    * List of extensions corresponding to file format types in WRITABLE_FNAMES
122    * that are writable by the application.
123    */
124   public static final String[] WRITABLE_EXTENSIONS = new String[] {
125       "fa, fasta, mfa, fastq", "aln", "pfam", "msf", "pir", "blc", "amsa",
126       "sto,stk", PhylipFile.FILE_EXT, JSONFile.FILE_EXT, "jvp" };
127
128   /**
129    * List of writable formats by the application. Order must correspond with the
130    * WRITABLE_EXTENSIONS list of formats.
131    */
132   public static final String[] WRITABLE_FNAMES = new String[] { "Fasta",
133       "Clustal", "PFAM", "MSF", "PIR", "BLC", "AMSA", "STH",
134       PhylipFile.FILE_DESC, JSONFile.FILE_DESC, "Jalview" };
135
136   public static String INVALID_CHARACTERS = "Contains invalid characters";
137
138   // TODO: make these messages dynamic
139   public static String SUPPORTED_FORMATS = "Formats currently supported are\n"
140           + prettyPrint(READABLE_FORMATS);
141
142   public AppletFormatAdapter()
143   {
144   }
145
146   public AppletFormatAdapter(AlignmentViewPanel viewpanel)
147   {
148     this.viewpanel = viewpanel;
149   }
150
151   public AppletFormatAdapter(AlignmentViewPanel alignPanel,
152           AlignExportSettingI settings)
153   {
154     viewpanel = alignPanel;
155     exportSettings = settings;
156   }
157
158   /**
159    *
160    * @param els
161    * @return grammatically correct(ish) list consisting of els elements.
162    */
163   public static String prettyPrint(String[] els)
164   {
165     StringBuffer list = new StringBuffer();
166     for (int i = 0, iSize = els.length - 1; i < iSize; i++)
167     {
168       list.append(els[i]);
169       list.append(", ");
170     }
171     list.append(" and " + els[els.length - 1] + ".");
172     return list.toString();
173   }
174
175   public void setNewlineString(String nl)
176   {
177     newline = nl;
178   }
179
180   public String getNewlineString()
181   {
182     return newline;
183   }
184
185   /**
186    * check that this format is valid for reading
187    *
188    * @param format
189    *          a format string to be compared with READABLE_FORMATS
190    * @return true if format is readable
191    */
192   public static final boolean isValidFormat(String format)
193   {
194     return isValidFormat(format, false);
195   }
196
197   /**
198    * validate format is valid for IO
199    *
200    * @param format
201    *          a format string to be compared with either READABLE_FORMATS or
202    *          WRITEABLE_FORMATS
203    * @param forwriting
204    *          when true, format is checked for containment in WRITEABLE_FORMATS
205    * @return true if format is valid
206    */
207   public static final boolean isValidFormat(String format,
208           boolean forwriting)
209   {
210     if (format == null)
211     {
212       return false;
213     }
214     boolean valid = false;
215     String[] format_list = (forwriting) ? WRITEABLE_FORMATS
216             : READABLE_FORMATS;
217     for (String element : format_list)
218     {
219       if (element.equalsIgnoreCase(format))
220       {
221         return true;
222       }
223     }
224
225     return valid;
226   }
227
228   /**
229    * Constructs the correct filetype parser for a characterised datasource
230    *
231    * @param inFile
232    *          data/data location
233    * @param type
234    *          type of datasource
235    * @param format
236    *          File format of data provided by datasource
237    *
238    * @return DOCUMENT ME!
239    */
240   public AlignmentI readFile(String inFile, String type, String format)
241           throws java.io.IOException
242   {
243     // TODO: generalise mapping between format string and io. class instances
244     // using Constructor.invoke reflection
245     this.inFile = inFile;
246     try
247     {
248       if (format.equals("FASTA"))
249       {
250         alignFile = new FastaFile(inFile, type);
251       }
252       else if (format.equals("MSF"))
253       {
254         alignFile = new MSFfile(inFile, type);
255       }
256       else if (format.equals("PileUp"))
257       {
258         alignFile = new PileUpfile(inFile, type);
259       }
260       else if (format.equals("CLUSTAL"))
261       {
262         alignFile = new ClustalFile(inFile, type);
263       }
264       else if (format.equals("BLC"))
265       {
266         alignFile = new BLCFile(inFile, type);
267       }
268       else if (format.equals("PIR"))
269       {
270         alignFile = new PIRFile(inFile, type);
271       }
272       else if (format.equals("PFAM"))
273       {
274         alignFile = new PfamFile(inFile, type);
275       }
276       else if (format.equals("JnetFile"))
277       {
278         alignFile = new JPredFile(inFile, type);
279         ((JPredFile) alignFile).removeNonSequences();
280       }
281       else if (format.equals("PDB") || format.equalsIgnoreCase("mmCIF"))
282       {
283         StructureImportSettings.addSettings(annotFromStructure,
284                 localSecondaryStruct, serviceSecondaryStruct);
285         alignFile = new JmolParser(inFile, type);
286         ((StructureFile) alignFile).setDbRefType(format);
287       }
288       else if (format.equals("STH"))
289       {
290         alignFile = new StockholmFile(inFile, type);
291       }
292       else if (format.equals("SimpleBLAST"))
293       {
294         alignFile = new SimpleBlastFile(inFile, type);
295       }
296       else if (format.equals(PhylipFile.FILE_DESC))
297       {
298         alignFile = new PhylipFile(inFile, type);
299       }
300       else if (format.equals(JSONFile.FILE_DESC))
301       {
302         alignFile = new JSONFile(inFile, type);
303       }
304       else if (format.equals(HtmlFile.FILE_DESC))
305       {
306         alignFile = new HtmlFile(inFile, type);
307       }
308       else if (format.equals("RNAML"))
309       {
310         alignFile = new RnamlFile(inFile, type);
311       }
312       else if (format.equals(IdentifyFile.FeaturesFile))
313       {
314         alignFile = new FeaturesFile(true, inFile, type);
315       }
316       return buildAlignmentFrom(alignFile);
317     } catch (Exception e)
318     {
319       e.printStackTrace();
320       System.err.println("Failed to read alignment using the '" + format
321               + "' reader.\n" + e);
322
323       if (e.getMessage() != null
324               && e.getMessage().startsWith(INVALID_CHARACTERS))
325       {
326         throw new java.io.IOException(e.getMessage());
327       }
328
329       // Finally test if the user has pasted just the sequence, no id
330       if (type.equalsIgnoreCase("Paste"))
331       {
332         try
333         {
334           // Possible sequence is just residues with no label
335           alignFile = new FastaFile(">UNKNOWN\n" + inFile, "Paste");
336           return buildAlignmentFrom(alignFile);
337
338         } catch (Exception ex)
339         {
340           if (ex.toString().startsWith(INVALID_CHARACTERS))
341           {
342             throw new java.io.IOException(e.getMessage());
343           }
344
345           ex.printStackTrace();
346         }
347       }
348       if (format.equalsIgnoreCase("HTML"))
349       {
350         throw new IOException(e.getMessage());
351       }
352       // If we get to this stage, the format was not supported
353       throw new java.io.IOException(SUPPORTED_FORMATS);
354     }
355   }
356
357   /**
358    * Constructs the correct filetype parser for an already open datasource
359    *
360    * @param source
361    *          an existing datasource
362    * @param format
363    *          File format of data that will be provided by datasource
364    *
365    * @return DOCUMENT ME!
366    */
367   public AlignmentI readFromFile(FileParse source, String format)
368           throws java.io.IOException
369   {
370     // TODO: generalise mapping between format string and io. class instances
371     // using Constructor.invoke reflection
372     // This is exactly the same as the readFile method except we substitute
373     // 'inFile, type' with 'source'
374     this.inFile = source.getInFile();
375     String type = source.type;
376     try
377     {
378       if (format.equals("FASTA"))
379       {
380         alignFile = new FastaFile(source);
381       }
382       else if (format.equals("MSF"))
383       {
384         alignFile = new MSFfile(source);
385       }
386       else if (format.equals("PileUp"))
387       {
388         alignFile = new PileUpfile(source);
389       }
390       else if (format.equals("CLUSTAL"))
391       {
392         alignFile = new ClustalFile(source);
393       }
394       else if (format.equals("BLC"))
395       {
396         alignFile = new BLCFile(source);
397       }
398       else if (format.equals("PIR"))
399       {
400         alignFile = new PIRFile(source);
401       }
402       else if (format.equals("PFAM"))
403       {
404         alignFile = new PfamFile(source);
405       }
406       else if (format.equals("JnetFile"))
407       {
408         alignFile = new JPredFile(source);
409         ((JPredFile) alignFile).removeNonSequences();
410       }
411       else if (format.equals("PDB"))
412       {
413         // TODO obtain config value from preference settings
414         boolean isParseWithJMOL = false;
415         if (isParseWithJMOL)
416         {
417           StructureImportSettings.addSettings(annotFromStructure,
418                   localSecondaryStruct, serviceSecondaryStruct);
419           alignFile = new JmolParser(source);
420         }
421         else
422         {
423           StructureImportSettings.setShowSeqFeatures(true);
424           alignFile = new MCview.PDBfile(annotFromStructure,
425                   localSecondaryStruct, serviceSecondaryStruct, source);
426         }
427         ((StructureFile) alignFile).setDbRefType(Type.PDB);
428       }
429       else if (format.equalsIgnoreCase("mmCIF"))
430       {
431         StructureImportSettings.addSettings(annotFromStructure,
432                 localSecondaryStruct, serviceSecondaryStruct);
433         alignFile = new JmolParser(source);
434         ((StructureFile) alignFile).setDbRefType(Type.MMCIF);
435       }
436       else if (format.equals("STH"))
437       {
438         alignFile = new StockholmFile(source);
439       }
440       else if (format.equals("RNAML"))
441       {
442         alignFile = new RnamlFile(source);
443       }
444       else if (format.equals("SimpleBLAST"))
445       {
446         alignFile = new SimpleBlastFile(source);
447       }
448       else if (format.equals(PhylipFile.FILE_DESC))
449       {
450         alignFile = new PhylipFile(source);
451       }
452       else if (format.equals(IdentifyFile.FeaturesFile))
453       {
454         alignFile = new FeaturesFile(inFile, type);
455       }
456       else if (format.equals(JSONFile.FILE_DESC))
457       {
458         alignFile = new JSONFile(source);
459       }
460       else if (format.equals(HtmlFile.FILE_DESC))
461       {
462         alignFile = new HtmlFile(source);
463       }
464
465       return buildAlignmentFrom(alignFile);
466
467     } catch (Exception e)
468     {
469       e.printStackTrace();
470       System.err.println("Failed to read alignment using the '" + format
471               + "' reader.\n" + e);
472
473       if (e.getMessage() != null
474               && e.getMessage().startsWith(INVALID_CHARACTERS))
475       {
476         throw new java.io.IOException(e.getMessage());
477       }
478
479       // Finally test if the user has pasted just the sequence, no id
480       if (type.equalsIgnoreCase("Paste"))
481       {
482         try
483         {
484           // Possible sequence is just residues with no label
485           alignFile = new FastaFile(">UNKNOWN\n" + inFile, "Paste");
486           return buildAlignmentFrom(alignFile);
487
488         } catch (Exception ex)
489         {
490           if (ex.toString().startsWith(INVALID_CHARACTERS))
491           {
492             throw new java.io.IOException(e.getMessage());
493           }
494
495           ex.printStackTrace();
496         }
497       }
498
499       // If we get to this stage, the format was not supported
500       throw new java.io.IOException(SUPPORTED_FORMATS);
501     }
502   }
503
504   /**
505    * boilerplate method to handle data from an AlignFile and construct a new
506    * alignment or import to an existing alignment
507    * 
508    * @param alignFile2
509    * @return AlignmentI instance ready to pass to a UI constructor
510    */
511   private AlignmentI buildAlignmentFrom(AlignFile alignFile2)
512   {
513     // Standard boilerplate for creating alignment from parser
514     // alignFile.configureForView(viewpanel);
515
516     AlignmentI al = new Alignment(alignFile.getSeqsAsArray());
517
518     alignFile.addAnnotations(al);
519
520     alignFile.addGroups(al);
521
522     return al;
523   }
524
525   /**
526    * create an alignment flatfile from a Jalview alignment view
527    * 
528    * @param format
529    * @param jvsuffix
530    * @param av
531    * @param selectedOnly
532    * @return flatfile in a string
533    */
534   public String formatSequences(String format, boolean jvsuffix,
535           AlignmentViewPanel ap, boolean selectedOnly)
536   {
537
538     AlignmentView selvew = ap.getAlignViewport().getAlignmentView(
539             selectedOnly, false);
540     AlignmentI aselview = selvew.getVisibleAlignment(ap.getAlignViewport()
541             .getGapCharacter());
542     List<AlignmentAnnotation> ala = (ap.getAlignViewport()
543             .getVisibleAlignmentAnnotation(selectedOnly));
544     if (ala != null)
545     {
546       for (AlignmentAnnotation aa : ala)
547       {
548         aselview.addAnnotation(aa);
549       }
550     }
551     viewpanel = ap;
552     return formatSequences(format, aselview, jvsuffix);
553   }
554
555   /**
556    * Construct an output class for an alignment in a particular filetype TODO:
557    * allow caller to detect errors and warnings encountered when generating
558    * output
559    *
560    * @param format
561    *          string name of alignment format
562    * @param alignment
563    *          the alignment to be written out
564    * @param jvsuffix
565    *          passed to AlnFile class controls whether /START-END is added to
566    *          sequence names
567    *
568    * @return alignment flat file contents
569    */
570   public String formatSequences(String format, AlignmentI alignment,
571           boolean jvsuffix)
572   {
573     try
574     {
575       AlignFile afile = null;
576       if (format.equalsIgnoreCase("FASTA"))
577       {
578         afile = new FastaFile();
579       }
580       else if (format.equalsIgnoreCase("MSF"))
581       {
582         afile = new MSFfile();
583       }
584       else if (format.equalsIgnoreCase("PileUp"))
585       {
586         afile = new PileUpfile();
587       }
588       else if (format.equalsIgnoreCase("CLUSTAL"))
589       {
590         afile = new ClustalFile();
591       }
592       else if (format.equalsIgnoreCase("BLC"))
593       {
594         afile = new BLCFile();
595       }
596       else if (format.equalsIgnoreCase("PIR"))
597       {
598         afile = new PIRFile();
599       }
600       else if (format.equalsIgnoreCase("PFAM"))
601       {
602         afile = new PfamFile();
603       }
604       else if (format.equalsIgnoreCase("STH"))
605       {
606         afile = new StockholmFile(alignment);
607       }
608       else if (format.equalsIgnoreCase("AMSA"))
609       {
610         afile = new AMSAFile(alignment);
611       }
612       else if (format.equalsIgnoreCase(PhylipFile.FILE_DESC))
613       {
614         afile = new PhylipFile();
615       }
616       else if (format.equalsIgnoreCase(JSONFile.FILE_DESC))
617       {
618         afile = new JSONFile();
619       }
620       else if (format.equalsIgnoreCase("RNAML"))
621       {
622         afile = new RnamlFile();
623       }
624
625       else
626       {
627         throw new Exception(
628                 MessageManager
629                         .getString("error.implementation_error_unknown_file_format_string"));
630       }
631
632       afile.setNewlineString(newline);
633       afile.addJVSuffix(jvsuffix);
634       afile.setExportSettings(exportSettings);
635       afile.configureForView(viewpanel);
636
637       // check whether we were given a specific alignment to export, rather than
638       // the one in the viewpanel
639       if (viewpanel == null || viewpanel.getAlignment() == null
640               || viewpanel.getAlignment() != alignment)
641       {
642         afile.setSeqs(alignment.getSequencesArray());
643       }
644       else
645       {
646         afile.setSeqs(viewpanel.getAlignment().getSequencesArray());
647       }
648
649       String afileresp = afile.print();
650       if (afile.hasWarningMessage())
651       {
652         System.err.println("Warning raised when writing as " + format
653                 + " : " + afile.getWarningMessage());
654       }
655       return afileresp;
656     } catch (Exception e)
657     {
658       System.err.println("Failed to write alignment as a '" + format
659               + "' file\n");
660       e.printStackTrace();
661     }
662
663     return null;
664   }
665
666   public static String checkProtocol(String file)
667   {
668     String protocol = FILE;
669     String ft = file.toLowerCase().trim();
670     if (ft.indexOf("http:") == 0 || ft.indexOf("https:") == 0
671             || ft.indexOf("file:") == 0)
672     {
673       protocol = URL;
674     }
675     return protocol;
676   }
677
678   public static void main(String[] args)
679   {
680     int i = 0;
681     while (i < args.length)
682     {
683       File f = new File(args[i]);
684       if (f.exists())
685       {
686         try
687         {
688           System.out.println("Reading file: " + f);
689           AppletFormatAdapter afa = new AppletFormatAdapter();
690           Runtime r = Runtime.getRuntime();
691           System.gc();
692           long memf = -r.totalMemory() + r.freeMemory();
693           long t1 = -System.currentTimeMillis();
694           AlignmentI al = afa.readFile(args[i], FILE,
695                   new IdentifyFile().identify(args[i], FILE));
696           t1 += System.currentTimeMillis();
697           System.gc();
698           memf += r.totalMemory() - r.freeMemory();
699           if (al != null)
700           {
701             System.out.println("Alignment contains " + al.getHeight()
702                     + " sequences and " + al.getWidth() + " columns.");
703             try
704             {
705               System.out.println(new AppletFormatAdapter().formatSequences(
706                       "FASTA", al, true));
707             } catch (Exception e)
708             {
709               System.err
710                       .println("Couln't format the alignment for output as a FASTA file.");
711               e.printStackTrace(System.err);
712             }
713           }
714           else
715           {
716             System.out.println("Couldn't read alignment");
717           }
718           System.out.println("Read took " + (t1 / 1000.0) + " seconds.");
719           System.out
720                   .println("Difference between free memory now and before is "
721                           + (memf / (1024.0 * 1024.0) * 1.0) + " MB");
722         } catch (Exception e)
723         {
724           System.err.println("Exception when dealing with " + i
725                   + "'th argument: " + args[i] + "\n" + e);
726         }
727       }
728       else
729       {
730         System.err.println("Ignoring argument '" + args[i] + "' (" + i
731                 + "'th)- not a readable file.");
732       }
733       i++;
734     }
735   }
736
737   /**
738    * try to discover how to access the given file as a valid datasource that
739    * will be identified as the given type.
740    *
741    * @param file
742    * @param format
743    * @return protocol that yields the data parsable as the given type
744    */
745   public static String resolveProtocol(String file, String format)
746   {
747     return resolveProtocol(file, format, false);
748   }
749
750   public static String resolveProtocol(String file, String format,
751           boolean debug)
752   {
753     // TODO: test thoroughly!
754     String protocol = null;
755     if (debug)
756     {
757       System.out.println("resolving datasource started with:\n>>file\n"
758               + file + ">>endfile");
759     }
760
761     // This might throw a security exception in certain browsers
762     // Netscape Communicator for instance.
763     try
764     {
765       boolean rtn = false;
766       InputStream is = System.getSecurityManager().getClass()
767               .getResourceAsStream("/" + file);
768       if (is != null)
769       {
770         rtn = true;
771         is.close();
772       }
773       if (debug)
774       {
775         System.err.println("Resource '" + file + "' was "
776                 + (rtn ? "" : "not") + " located by classloader.");
777       }
778       ;
779       if (rtn)
780       {
781         protocol = AppletFormatAdapter.CLASSLOADER;
782       }
783
784     } catch (Exception ex)
785     {
786       System.err
787               .println("Exception checking resources: " + file + " " + ex);
788     }
789
790     if (file.indexOf("://") > -1)
791     {
792       protocol = AppletFormatAdapter.URL;
793     }
794     else
795     {
796       // skipping codebase prepend check.
797       protocol = AppletFormatAdapter.FILE;
798     }
799     FileParse fp = null;
800     try
801     {
802       if (debug)
803       {
804         System.out.println("Trying to get contents of resource as "
805                 + protocol + ":");
806       }
807       fp = new FileParse(file, protocol);
808       if (!fp.isValid())
809       {
810         fp = null;
811       }
812       else
813       {
814         if (debug)
815         {
816           System.out.println("Successful.");
817         }
818       }
819     } catch (Exception e)
820     {
821       if (debug)
822       {
823         System.err.println("Exception when accessing content: " + e);
824       }
825       fp = null;
826     }
827     if (fp == null)
828     {
829       if (debug)
830       {
831         System.out.println("Accessing as paste.");
832       }
833       protocol = AppletFormatAdapter.PASTE;
834       fp = null;
835       try
836       {
837         fp = new FileParse(file, protocol);
838         if (!fp.isValid())
839         {
840           fp = null;
841         }
842       } catch (Exception e)
843       {
844         System.err.println("Failed to access content as paste!");
845         e.printStackTrace();
846         fp = null;
847       }
848     }
849     if (fp == null)
850     {
851       return null;
852     }
853     if (format == null || format.length() == 0)
854     {
855       return protocol;
856     }
857     else
858     {
859       try
860       {
861         String idformat = new jalview.io.IdentifyFile().identify(file,
862                 protocol);
863         if (idformat == null)
864         {
865           if (debug)
866           {
867             System.out.println("Format not identified. Inaccessible file.");
868           }
869           return null;
870         }
871         if (debug)
872         {
873           System.out.println("Format identified as " + idformat
874                   + "and expected as " + format);
875         }
876         if (idformat.equals(format))
877         {
878           if (debug)
879           {
880             System.out.println("Protocol identified as " + protocol);
881           }
882           return protocol;
883         }
884         else
885         {
886           if (debug)
887           {
888             System.out
889                     .println("File deemed not accessible via " + protocol);
890           }
891           fp.close();
892           return null;
893         }
894       } catch (Exception e)
895       {
896         if (debug)
897         {
898           System.err.println("File deemed not accessible via " + protocol);
899           e.printStackTrace();
900         }
901         ;
902
903       }
904     }
905     return null;
906   }
907
908   public AlignFile getAlignFile()
909   {
910     return alignFile;
911   }
912
913   public void setAlignFile(AlignFile alignFile)
914   {
915     this.alignFile = alignFile;
916   }
917 }