JAL-1499 refactored processGeneOrDomain, expanded test
[jalview.git] / src / jalview / io / MegaFile.java
index c7caa3b..eb9868b 100644 (file)
@@ -105,6 +105,8 @@ public class MegaFile extends AlignFile
 
   private static final String CODONSTART = "CodonStart";
 
+  private static final String LABEL = "Label";
+
   /*
    * names of properties to save to the alignment (may affect eventual output
    * format)
@@ -241,6 +243,10 @@ public class MegaFile extends AlignFile
         {
           parseGeneOrDomain(dataLine);
         }
+        else if (dataLine.startsWith(BANG + LABEL))
+        {
+          parseLabel(dataLine);
+        }
         else
         {
           currentSequenceId = parseDataLine(dataLine);
@@ -269,6 +275,17 @@ public class MegaFile extends AlignFile
   }
 
   /**
+   * Parse a !Label
+   * 
+   * @param dataLine
+   */
+  protected void parseLabel(String dataLine)
+  {
+    // TODO Auto-generated method stub
+
+  }
+
+  /**
    * Post-processing after reading one block of interleaved data
    */
   protected void endOfDataBlock()
@@ -362,42 +379,136 @@ public class MegaFile extends AlignFile
   protected void processGeneOrDomain(String gene, String domain,
           String property, String codonStart)
   {
-    boolean domainEnd = "domainend".equalsIgnoreCase(property);
-
     /*
-     * If we have been processing a Domain or Gene, and this does not continue
-     * it, then close it off (generate sequence features for it). Do Domain
-     * first as it is in the context of the enclosing gene if any.
+     * the order of processing below ensures that we correctly capture where a
+     * domain is in the context of an enclosing gene
      */
-    if (this.currentDomain != null)
+    processDomainEnd(domain, property);
+
+    processGeneEnd(gene);
+
+    processGeneStart(gene);
+
+    processDomainStart(domain, property);
+
+    // TODO save codonStart if we plan to involve it in 'translate as cDNA'
+  }
+
+  /**
+   * If we have declared a domain, and it is not continuing, start a sequence
+   * feature for it
+   * 
+   * @param domain
+   * @param property
+   */
+  protected void processDomainStart(String domain, String property)
+  {
+    if ("domainend".equalsIgnoreCase(property))
     {
-      if (!this.currentDomain.equals(domain) || domainEnd)
-      {
-        String description = currentDomain
-                + (currentGene == null ? "" : " (" + currentGene + ")");
-        createFeature(DOMAIN, description, domainStart);
-      }
+      currentDomain = null;
+      return;
     }
-    if (this.currentGene != null && !this.currentGene.equals(gene))
+
+    if (domain != null && !domain.equals(currentDomain))
     {
-      createFeature(GENE, currentGene, geneStart);
+      String verboseDomain = makeVerboseDomainName(domain, property);
+      startSequenceFeature(domainStart);
+
+      currentDomain = verboseDomain;
     }
+  }
 
-    /*
-     * and if we have declared a Gene or Domain which does not continue the
-     * current one, then record its start positions per sequence
-     */
+  /**
+   * If we have declared a gene, and it is not continuing, start a sequence
+   * feature for it
+   * 
+   * @param gene
+   */
+  protected void processGeneStart(String gene)
+  {
     if (gene != null && !gene.equals(currentGene))
     {
       startSequenceFeature(geneStart);
     }
-    if (domain != null && !domain.equals(currentDomain))
+    currentGene = gene;
+  }
+
+  /**
+   * If we have been processing a domain, and it is not being continued, then
+   * make a sequence feature for the domain just ended
+   * 
+   * @param domain
+   * @param property
+   * @return true if a feature is created, else false
+   */
+  protected boolean processDomainEnd(String domain, String property)
+  {
+    String verboseDomain = makeVerboseDomainName(domain, property);
+    if (this.currentDomain != null)
     {
-      startSequenceFeature(domainStart);
+      boolean domainEnded = "domainend".equalsIgnoreCase(property);
+      if (!this.currentDomain.equals(verboseDomain) || domainEnded)
+      {
+        createFeature(DOMAIN, currentDomain, domainStart);
+        return true;
+      }
     }
+    return false;
+  }
 
-    currentGene = gene;
-    currentDomain = domainEnd ? null : domain;
+  /**
+   * If we have been processing a gene, and it is not being continued, then make
+   * a sequence feature for the gene just ended
+   * 
+   * @param gene
+   * @return true if a feature is created, else false
+   */
+  protected boolean processGeneEnd(String gene)
+  {
+    boolean created = false;
+    /*
+     * If we were processing a gene and now have either another, or none, create
+     * a sequence feature for that gene
+     */
+    if (this.currentGene != null && !this.currentGene.equals(gene))
+    {
+      createFeature(GENE, currentGene, geneStart);
+      created = true;
+    }
+
+    return created;
+  }
+
+  /**
+   * Makes an expanded descriptive name for Domain if possible e.g.
+   * "Intron1 (Adh Coding)". Currently incorporates the current gene name (if
+   * any) and the Coding/Noncoding property value (if given).
+   * 
+   * @param domain
+   * @param property
+   * @return
+   */
+  protected String makeVerboseDomainName(String domain, String property)
+  {
+    String verboseDomain = domain;
+    if (domain != null)
+    {
+      String coding = "";
+      if ("Exon".equalsIgnoreCase(property)
+              || "Coding".equalsIgnoreCase(property))
+      {
+        coding = " Coding";
+      }
+      else if ("Intron".equalsIgnoreCase(property)
+              || "Noncoding".equalsIgnoreCase(property))
+      {
+        coding = " Noncoding";
+      }
+      verboseDomain = domain
+              + (currentGene == null ? "" : " (" + currentGene + coding
+                      + ")");
+    }
+    return verboseDomain;
   }
 
   /**
@@ -1391,9 +1502,8 @@ public class MegaFile extends AlignFile
   {
     if (this.interleaved != null && isIt != this.interleaved.booleanValue())
     {
-      throw new FileFormatException(
-              "Parse error: mix of interleaved and noninterleaved detected, at line: "
-                      + dataLine);
+      throw new FileFormatException("Parse error: interleaved was " + !isIt
+              + " but now seems to be " + isIt + ", at line: " + dataLine);
     }
     this.interleaved = new Boolean(isIt);
     setAlignmentProperty(PROP_INTERLEAVED, interleaved.toString());