JAL-2136 broken build fix attempt
[jalview.git] / src / jalview / io / AnnotationFile.java
index 2af3fcd..206d971 100755 (executable)
@@ -28,15 +28,18 @@ import jalview.datamodel.Annotation;
 import jalview.datamodel.ColumnSelection;
 import jalview.datamodel.GraphLine;
 import jalview.datamodel.HiddenSequences;
+import jalview.datamodel.PDBEntry;
+import jalview.datamodel.PDBEntry.Type;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
 import jalview.schemes.ColourSchemeI;
 import jalview.schemes.ColourSchemeProperty;
-import jalview.schemes.UserColourScheme;
+import jalview.structure.StructureSelectionManager;
 import jalview.util.ColorUtils;
 
 import java.awt.Color;
 import java.io.BufferedReader;
+import java.io.File;
 import java.io.FileReader;
 import java.io.InputStreamReader;
 import java.io.StringReader;
@@ -52,6 +55,28 @@ import java.util.Vector;
 
 public class AnnotationFile
 {
+  StringBuffer text;
+
+  SequenceI refSeq = null;
+
+  String refSeqId = null;
+
+  String[] StructModelHeader = null;
+
+  long nlinesread = 0;
+
+  String lastread = "";
+
+  /**
+   * used for resolving absolute references to resources relative to
+   * annotationFile location
+   */
+  String baseUri = "";
+
+  private static String GRAPHLINE = "GRAPHLINE", COMBINE = "COMBINE",
+          STRUCTMODEL = "STRUCTMODEL",
+          HEADER_STRUCT_MODEL = "HEADER_STRUCT_MODEL";
+
   public AnnotationFile()
   {
     init();
@@ -78,7 +103,6 @@ public class AnnotationFile
     return newline;
   }
 
-  StringBuffer text;
 
   private void init()
   {
@@ -657,9 +681,6 @@ public class AnnotationFile
     }
   }
 
-  SequenceI refSeq = null;
-
-  String refSeqId = null;
 
   public boolean annotateAlignmentView(AlignViewportI viewport,
           String file, DataSourceType protocol)
@@ -688,21 +709,41 @@ public class AnnotationFile
   public boolean readAnnotationFile(AlignmentI al, ColumnSelection colSel,
           String file, DataSourceType sourceType)
   {
+    baseUri = "";
     BufferedReader in = null;
     try
     {
       if (sourceType == DataSourceType.FILE)
       {
         in = new BufferedReader(new FileReader(file));
+        baseUri = new File(file).getParent();
+        if (baseUri == null)
+        {
+          baseUri = "";
+        }
+        else
+        {
+          baseUri += "/";
+        }
       }
       else if (sourceType == DataSourceType.URL)
       {
         URL url = new URL(file);
         in = new BufferedReader(new InputStreamReader(url.openStream()));
+        String bs = url.toExternalForm();
+        baseUri = bs.substring(0, bs.indexOf(url.getHost())
+                + url.getHost().length());
+        baseUri += url.toURI().getPath();
+        if (baseUri.lastIndexOf("/") > -1)
+        {
+          baseUri = baseUri.substring(0, baseUri.lastIndexOf("/")) + "/";
+        }
       }
       else if (sourceType == DataSourceType.PASTE)
       {
         in = new BufferedReader(new StringReader(file));
+        // TODO - support mimencoded PDBs for a paste.. ?
+        baseUri = "";
       }
       else if (sourceType == DataSourceType.CLASSLOADER)
       {
@@ -710,6 +751,8 @@ public class AnnotationFile
         if (is != null)
         {
           in = new BufferedReader(new java.io.InputStreamReader(is));
+          // TODO: this probably doesn't work for classloader - needs a test
+          baseUri = new File("/" + file).getParent() + "/";
         }
       }
       if (in != null)
@@ -731,11 +774,6 @@ public class AnnotationFile
     return false;
   }
 
-  long nlinesread = 0;
-
-  String lastread = "";
-
-  private static String GRAPHLINE = "GRAPHLINE", COMBINE = "COMBINE";
 
   public boolean parseAnnotationFrom(AlignmentI al, ColumnSelection colSel,
           BufferedReader in) throws Exception
@@ -929,12 +967,6 @@ public class AnnotationFile
           modified = true;
           continue;
         }
-        // else if (token.equalsIgnoreCase("VIEW_DEF"))
-        // {
-        // addOrSetView(al,st);
-        // modified = true;
-        // continue;
-        // }
         else if (token.equalsIgnoreCase("VIEW_SETREF"))
         {
           if (refSeq != null)
@@ -981,7 +1013,58 @@ public class AnnotationFile
           modified = true;
           continue;
         }
-
+        else if (token.equalsIgnoreCase(HEADER_STRUCT_MODEL))
+        {
+          int hSize = st.countTokens();
+          StructModelHeader = new String[hSize];
+          for (int x = 0; x < hSize; x++)
+          {
+            StructModelHeader[x] = st.nextToken();
+          }
+          continue;
+        }
+        else if (token.equalsIgnoreCase(STRUCTMODEL))
+        {
+          boolean failedtoadd = true;
+          // expects STRUCTMODEL <Query> <TemplateSeqId> <ModelFile>
+          // <FastaMappingFile>
+          String querySeqId = !st.hasMoreTokens() ? "" : st.nextToken();
+          SequenceI querySeq = al.findName(querySeqId);
+          if (st.hasMoreTokens()) {
+            refSeq = al.findName(refSeqId = st.nextToken());
+            if (refSeq == null)
+            {
+              System.err.println("Couldn't locate " + refSeqId
+                      + " in the alignment for STRUCTMODEL");
+              refSeqId = null;
+            }
+            else
+            {
+              int tSize = st.countTokens() + 2;
+              String[] rowData = new String[tSize];
+              rowData[0] = querySeqId;
+              rowData[1] = refSeqId;
+              for (int x = 2; x < tSize; x++)
+              {
+                rowData[x] = st.nextToken();
+              }
+              if (processStructModel(al, querySeq, refSeq,
+                      StructModelHeader, rowData, baseUri))
+              {
+                failedtoadd = false;
+              }
+            }
+          }
+          if (failedtoadd)
+          {
+            System.err
+                    .println("Need minimum of <Query> <TemplateSeqId> <ModelFile> <FastaMappingFile> as tab separated fields after"
+                            + STRUCTMODEL);
+          } else {
+            modified = true;
+          }
+          continue;
+        }
         // Parse out the annotation row
         graphStyle = AlignmentAnnotation.getGraphValueFromString(token);
         label = st.nextToken();
@@ -1181,6 +1264,103 @@ public class AnnotationFile
     return modified;
   }
 
+  /**
+   * Resolve structural model to a reference sequence and register it to
+   * StructureSelectionManager
+   * 
+   * @param al
+   * @param querySequence
+   * @param templateSeq
+   * @param structModelHeader
+   * @param structModelData
+   * @return true if model and sequence was added
+   */
+  static boolean processStructModel(AlignmentI al, SequenceI querySequence,
+          SequenceI templateSeq,
+ String[] structModelHeader,
+          String[] structModelData, String baseUri)
+  {
+    String warningMessage = null;
+    boolean added = false;
+    try {
+      String structureModelFile = resolveAbsolutePath(structModelData[2],
+              baseUri);
+      String fastaMappingFile = resolveAbsolutePath(structModelData[3],
+              baseUri);
+      // System.out.println("Model File >> " + structureModelFile);
+      // System.out.println("Fasta File >> " + fastaMappingFile);
+      String modelName = StructureFile.safeName(structureModelFile);
+      PDBEntry phyre2PDBEntry = new PDBEntry(modelName, " ",
+              Type.PDB,
+              structureModelFile);
+      String phyre2ModelDesc = generatePhyre2InfoHTMLTable(
+              structModelHeader, structModelData);
+      phyre2PDBEntry.setProperty("PHYRE2_MODEL_INFO", phyre2ModelDesc);
+      templateSeq.getDatasetSequence().addPDBId(phyre2PDBEntry);
+      if (querySequence != null)
+      {
+        querySequence.getDatasetSequence().addPDBId(phyre2PDBEntry);
+      }
+      StructureSelectionManager ssm = StructureSelectionManager
+              .getStructureSelectionManager();
+      ssm.registerPhyre2Template(structureModelFile, fastaMappingFile);
+      added = true;
+
+    } catch (Exception x)
+    {
+      warningMessage = x.toString();
+    } finally {
+      if (warningMessage !=null)
+      {
+        System.err.println("Warnings whilst processing STRUCTMODEL: "+warningMessage);
+      }
+    }
+    return added;
+  }
+
+  static String generatePhyre2InfoHTMLTable(String[] structModelHeader,
+          String[] structModelData)
+  {
+    StringBuilder phyre2InfoBuilder = new StringBuilder();
+    if (isGenerateStructInfoHtml(structModelHeader, structModelData))
+    {
+      phyre2InfoBuilder.append("<html><table border=\"1\" width=100%>")
+              .append("<tr><td colspan=\"2\"><strong>Phyre2 Template Info</strong></td></tr>");
+      for (int x = 4; x < structModelData.length; x++)
+      {
+        phyre2InfoBuilder.append("<tr><td>").append(structModelHeader[x])
+                .append("</td><td>").append(structModelData[x])
+                .append("</td></tr>");
+      }
+      phyre2InfoBuilder.append("</table></html>");
+    }
+    return phyre2InfoBuilder.toString();
+  }
+
+  static boolean isGenerateStructInfoHtml(String[] header, String[] data)
+  {
+    boolean generate = true;
+    if (header == null || data == null)
+    {
+      return false;
+    }
+    if (header.length < 3 || data.length < 3)
+    {
+      generate = false;
+    }
+    return generate;
+  }
+
+  static String resolveAbsolutePath(String relURI, String _baseUri)
+  {
+    if (relURI.indexOf(":/") > -1 || relURI.startsWith("/")
+            || "".equals(_baseUri) || relURI.startsWith(_baseUri))
+    {
+      return relURI;
+    }
+    return _baseUri + relURI;
+  }
+
   private void parseHideCols(ColumnSelection colSel, String nextToken)
   {
     StringTokenizer inval = new StringTokenizer(nextToken, ",");
@@ -1610,8 +1790,7 @@ public class AnnotationFile
     if (sg != null)
     {
       String keyValue, key, value;
-      ColourSchemeI def = sg.cs;
-      sg.cs = null;
+      ColourSchemeI def = sg.getColourScheme();
       while (st.hasMoreTokens())
       {
         keyValue = st.nextToken();
@@ -1624,7 +1803,8 @@ public class AnnotationFile
         }
         else if (key.equalsIgnoreCase("colour"))
         {
-          sg.cs = ColourSchemeProperty.getColourScheme(al, value);
+          sg.cs.setColourScheme(ColourSchemeProperty
+                  .getColourScheme(al, value));
         }
         else if (key.equalsIgnoreCase("pidThreshold"))
         {
@@ -1677,9 +1857,8 @@ public class AnnotationFile
         }
         else if (key.equalsIgnoreCase("idColour"))
         {
-          // consider warning if colour doesn't resolve to a real colour
-          def = new UserColourScheme(value);
-          sg.setIdColour(def.findColour());
+          Color idColour = ColorUtils.parseColourString(value);
+          sg.setIdColour(idColour == null ? Color.black : idColour);
         }
         else if (key.equalsIgnoreCase("hide"))
         {
@@ -1693,9 +1872,9 @@ public class AnnotationFile
         }
         sg.recalcConservation();
       }
-      if (sg.cs == null)
+      if (sg.getColourScheme() == null)
       {
-        sg.cs = def;
+        sg.setColourScheme(def);
       }
     }
   }