valid format for writing test
[jalview.git] / src / jalview / io / AppletFormatAdapter.java
index fbfaab1..c7b0575 100755 (executable)
  */
 package jalview.io;
 
+import java.io.File;
+
 import jalview.datamodel.*;
 
 /**
- * DOCUMENT ME!
+ * A low level class for alignment and feature IO
+ * with alignment formatting methods used by both applet 
+ * and application for generating flat alignment files.
+ * It also holds the lists of magic format names
+ * that the applet and application will allow the user to read or write files with.
  *
  * @author $author$
  * @version $Revision$
  */
 public class AppletFormatAdapter
 {
-  /** DOCUMENT ME!! */
+  /** 
+   * List of valid format strings used in the isValidFormat method 
+   */
   public static final String[] READABLE_FORMATS = new String[]
       {
       "BLC", "CLUSTAL", "FASTA", "MSF", "PileUp", "PIR", "PFAM", "STH", "PDB", "JnetFile"
   };
-
+  /**
+   * List of valid format strings for use by callers of the formatSequences method
+   */
   public static final String[] WRITEABLE_FORMATS = new String[]
       {
       "BLC", "CLUSTAL", "FASTA", "MSF", "PileUp", "PIR", "PFAM" , "AMSA"
   };
-
+  /**
+   * List of extensions corresponding to file format types 
+   * in WRITABLE_FNAMES that are writable by the
+   * application.
+   */
   public static final String[] WRITABLE_EXTENSIONS = new String[]
         { "fa, fasta, fastq", "aln", "pfam", "msf", "pir", "blc","amsa","jar" };
-
+  /**
+   * List of writable formats by the application. Order must
+   * correspond with the WRITABLE_EXTENSIONS list of formats.
+   */
   public static final String[] WRITABLE_FNAMES = new String[]
         { "Fasta", "Clustal", "PFAM", "MSF", "PIR", "BLC", "AMSA", "Jalview" };
 
+  /**
+   * List of readable format file extensions by application in order
+   * corresponding to READABLE_FNAMES 
+   */
   public static final String[] READABLE_EXTENSIONS =         new String[]
         {
         "fa, fasta, fastq", "aln", "pfam", "msf", "pir", "blc",
         "amsa","jar"
     };
+  /**
+   * List of readable formats by application in order
+   * corresponding to READABLE_EXTENSIONS
+   */
   public static final String[] READABLE_FNAMES =         new String[]
         {
         "Fasta", "Clustal", "PFAM", "MSF", "PIR", "BLC", "AMSA","Jalview"
@@ -88,10 +113,21 @@ public class AppletFormatAdapter
    */
   public static final boolean isValidFormat(String format)
   {
+    return isValidFormat(format, false);
+  }
+  /**
+   * validate format is valid for IO
+   * @param format a format string to be compared with either READABLE_FORMATS or WRITEABLE_FORMATS
+   * @param forwriting when true, format is checked for containment in WRITEABLE_FORMATS
+   * @return true if format is valid
+   */
+  public static final boolean isValidFormat(String format, boolean forwriting)
+  {
     boolean valid = false;
-    for (int i = 0; i < READABLE_FORMATS.length; i++)
+    String[] format_list = (forwriting) ? WRITEABLE_FORMATS : READABLE_FORMATS;
+    for (int i = 0; i < format_list.length; i++)
     {
-      if (READABLE_FORMATS[i].equalsIgnoreCase(format))
+      if (format_list[i].equalsIgnoreCase(format))
       {
         return true;
       }
@@ -99,7 +135,7 @@ public class AppletFormatAdapter
 
     return valid;
   }
-
+  
   /**
    * Constructs the correct filetype parser for a characterised datasource
    *
@@ -112,6 +148,7 @@ public class AppletFormatAdapter
   public Alignment readFile(String inFile, String type, String format)
       throws java.io.IOException
   {
+    // TODO: generalise mapping between format string and io. class instances using Constructor.invoke reflection
     this.inFile = inFile;
     try
     {
@@ -202,13 +239,117 @@ public class AppletFormatAdapter
       throw new java.io.IOException(SUPPORTED_FORMATS);
     }
   }
+  /**
+   * Constructs the correct filetype parser for an already open datasource
+   *
+   * @param source an existing datasource
+   * @param format File format of data that will be provided by datasource
+   *
+   * @return DOCUMENT ME!
+   */
+  public Alignment readFromFile(FileParse source, String format)
+      throws java.io.IOException
+  {
+    // TODO: generalise mapping between format string and io. class instances using Constructor.invoke reflection
+    // This is exactly the same as the readFile method except we substitute 'inFile, type' with 'source'
+    this.inFile = source.getInFile();
+    String type = source.type;
+    try
+    {
+      if (format.equals("FASTA"))
+      {
+        afile = new FastaFile(source);
+      }
+      else if (format.equals("MSF"))
+      {
+        afile = new MSFfile(source);
+      }
+      else if (format.equals("PileUp"))
+      {
+        afile = new PileUpfile(source);
+      }
+      else if (format.equals("CLUSTAL"))
+      {
+        afile = new ClustalFile(source);
+      }
+      else if (format.equals("BLC"))
+      {
+        afile = new BLCFile(source);
+      }
+      else if (format.equals("PIR"))
+      {
+        afile = new PIRFile(source);
+      }
+      else if (format.equals("PFAM"))
+      {
+        afile = new PfamFile(source);
+      }
+      else if (format.equals("JnetFile"))
+      {
+        afile = new JPredFile(source);
+        ( (JPredFile) afile).removeNonSequences();
+      }
+      else if (format.equals("PDB"))
+      {
+        afile = new MCview.PDBfile(source);
+      }
+      else if (format.equals("STH"))
+      {
+        afile = new StockholmFile(source);
+      }
+
+      Alignment al = new Alignment(afile.getSeqsAsArray());
+
+      afile.addAnnotations(al);
+
+      return al;
+    }
+    catch (Exception e)
+    {
+      e.printStackTrace();
+      System.err.println("Failed to read alignment using the '" + format +
+                         "' reader.\n" + e);
+
+      if (e.getMessage() != null &&
+          e.getMessage().startsWith(INVALID_CHARACTERS))
+      {
+        throw new java.io.IOException(e.getMessage());
+      }
+
+      // Finally test if the user has pasted just the sequence, no id
+      if (type.equalsIgnoreCase("Paste"))
+      {
+        try
+        {
+          // Possible sequence is just residues with no label
+          afile = new FastaFile(">UNKNOWN\n" + inFile, "Paste");
+          Alignment al = new Alignment(afile.getSeqsAsArray());
+          afile.addAnnotations(al);
+          return al;
 
+        }
+        catch (Exception ex)
+        {
+          if (ex.toString().startsWith(INVALID_CHARACTERS))
+          {
+            throw new java.io.IOException(e.getMessage());
+          }
+
+          ex.printStackTrace();
+        }
+      }
+
+      // If we get to this stage, the format was not supported
+      throw new java.io.IOException(SUPPORTED_FORMATS);
+    }
+  }
+  
   /**
    * Construct an output class for an alignment in a particular filetype
    *
-   * @param format DOCUMENT ME!
-   * @param seqs DOCUMENT ME!
-   * @param jvsuffix passed to AlnFile class
+   * @param format string name of alignment format 
+   * @param alignment the alignment to be written out
+   * @param jvsuffix passed to AlnFile class controls whether /START-END is added to sequence names
    *
    * @return alignment flat file contents
    */
@@ -274,4 +415,43 @@ public class AppletFormatAdapter
 
     return null;
   }
+  public static void main(String[] args)
+  {
+    int i=0;
+    while (i<args.length)
+    {
+      File f = new File(args[i]);
+      if (f.exists())
+      {
+        try {
+          System.out.println("Reading file: "+f);
+          AppletFormatAdapter afa = new AppletFormatAdapter();
+          Runtime r = Runtime.getRuntime();
+          System.gc();
+          long memf = -r.totalMemory()+r.freeMemory();
+          long t1 = -System.currentTimeMillis();
+          Alignment al = afa.readFile(args[i], FILE, new IdentifyFile().Identify(args[i], FILE));
+          t1 +=System.currentTimeMillis();
+          System.gc();
+          memf += r.totalMemory()-r.freeMemory();
+          if (al!=null)
+          {
+            System.out.println("Alignment contains "+al.getHeight()+" sequences and "+al.getWidth()+" columns.");
+          } else {
+            System.out.println("Couldn't read alignment");
+          }
+          System.out.println("Read took "+(t1/1000.0)+" seconds.");
+          System.out.println("Difference between free memory now and before is "+(memf/(1024.0*1024.0)*1.0)+" MB");
+          
+        } catch (Exception e)
+        {
+          System.err.println("Exception when dealing with "+i+"'th argument: "+args[i]+"\n"+e);
+        }
+      } else {
+          System.err.println("Ignoring argument '"+args[i]+"' ("+i+"'th)- not a readable file.");
+      }
+      i++;
+    }
+    
+  }
 }