No stacktrace
[jalview.git] / src / jalview / io / FeaturesFile.java
index a83dff8..c32fbc9 100755 (executable)
@@ -1,6 +1,6 @@
 /*\r
 * Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
 *\r
 * This program is free software; you can redistribute it and/or\r
 * modify it under the terms of the GNU General Public License\r
@@ -40,15 +40,6 @@ public class FeaturesFile extends AlignFile
     {\r
     }\r
 \r
-    /**\r
-     * Creates a new FeaturesFile object.\r
-     *\r
-     * @param inStr DOCUMENT ME!\r
-     */\r
-    public FeaturesFile(String inStr)\r
-    {\r
-        super(inStr);\r
-    }\r
 \r
     /**\r
      * Creates a new FeaturesFile object.\r
@@ -65,12 +56,29 @@ public class FeaturesFile extends AlignFile
     }\r
 \r
     /**\r
-     * DOCUMENT ME!\r
+     * The Application can render HTML, but the applet will\r
+     * remove HTML tags and replace links with %LINK%\r
+     * Both need to read links in HTML however\r
+     *\r
+     * @throws IOException DOCUMENT ME!\r
+     */\r
+    public boolean parse(AlignmentI align,\r
+                         Hashtable colours,\r
+                         boolean removeHTML)\r
+    {\r
+      return parse(align, colours, null, removeHTML);\r
+    }\r
+    /**\r
+     * The Application can render HTML, but the applet will\r
+     * remove HTML tags and replace links with %LINK%\r
+     * Both need to read links in HTML however\r
      *\r
      * @throws IOException DOCUMENT ME!\r
      */\r
-    public boolean parse(AlignmentI align,  Hashtable colours)\r
-        throws IOException\r
+    public boolean parse(AlignmentI align,\r
+                         Hashtable colours,\r
+                         Hashtable featureLink,\r
+                         boolean removeHTML)\r
     {\r
       String line = null;\r
       try\r
@@ -82,7 +90,8 @@ public class FeaturesFile extends AlignFile
         float score;\r
         StringTokenizer st;\r
         SequenceFeature sf;\r
-        String featureGroup = null;\r
+        String featureGroup = null, groupLink = null;\r
+        Hashtable typeLink = new Hashtable();\r
 \r
         boolean GFFFile = true;\r
 \r
@@ -99,6 +108,11 @@ public class FeaturesFile extends AlignFile
             if (type.equalsIgnoreCase("startgroup"))\r
             {\r
               featureGroup = st.nextToken();\r
+              if (st.hasMoreElements())\r
+              {\r
+                groupLink = st.nextToken();\r
+                featureLink.put(featureGroup, groupLink);\r
+              }\r
             }\r
             else if (type.equalsIgnoreCase("endgroup"))\r
             {\r
@@ -106,11 +120,21 @@ public class FeaturesFile extends AlignFile
               //but at present theres no way of showing more than 1 group\r
               st.nextToken();\r
               featureGroup = null;\r
+              groupLink = null;\r
             }\r
             else\r
             {\r
               UserColourScheme ucs = new UserColourScheme(st.nextToken());\r
               colours.put(type, ucs.findColour("A"));\r
+              if (st.hasMoreElements())\r
+              {\r
+                String link = st.nextToken();\r
+                typeLink.put(type, link);\r
+                if(featureLink==null)\r
+                  featureLink = new Hashtable();\r
+                featureLink.put(type, link);\r
+              }\r
+\r
             }\r
             continue;\r
           }\r
@@ -132,7 +156,7 @@ public class FeaturesFile extends AlignFile
                 end = Integer.parseInt(st.nextToken());\r
                 try\r
                 {\r
-                  score = Float.parseFloat(st.nextToken());\r
+                  score =  new Float(st.nextToken()).floatValue();\r
                 }\r
                 catch (NumberFormatException ex)\r
                 {\r
@@ -149,7 +173,17 @@ public class FeaturesFile extends AlignFile
                 catch (Exception ex)\r
                 {}\r
 \r
-                seq.getDatasetSequence().addSequenceFeature(sf);\r
+                if(st.hasMoreTokens())\r
+                {\r
+                  StringBuffer attributes = new StringBuffer();\r
+                  while (st.hasMoreTokens())\r
+                  {\r
+                    attributes.append("\t"+st.nextElement());\r
+                  }\r
+                  sf.setValue("ATTRIBUTES", attributes.toString());\r
+                }\r
+\r
+                seq.addSequenceFeature(sf);\r
 \r
                 break;\r
               }\r
@@ -201,7 +235,20 @@ public class FeaturesFile extends AlignFile
 \r
             sf = new SequenceFeature(type, desc, "", start, end, featureGroup);\r
 \r
-            seq.getDatasetSequence().addSequenceFeature(sf);\r
+            seq.addSequenceFeature(sf);\r
+\r
+            if(groupLink!=null && removeHTML)\r
+            {\r
+              sf.addLink(groupLink);\r
+              sf.description += "%LINK%";\r
+            }\r
+            if(typeLink.containsKey(type) && removeHTML)\r
+            {\r
+              sf.addLink(typeLink.get(type).toString());\r
+              sf.description += "%LINK%";\r
+            }\r
+\r
+            parseDescriptionHTML(sf, removeHTML);\r
 \r
             //If we got here, its not a GFFFile\r
             GFFFile = false;\r
@@ -211,15 +258,40 @@ public class FeaturesFile extends AlignFile
       catch (Exception ex)\r
       {\r
         System.out.println(line);\r
-        ex.printStackTrace();\r
-        System.out.println("Error parsing groups file: " + ex +"\n"+line);\r
+        System.out.println("Error parsing feature file: " + ex +"\n"+line);\r
         return false;\r
       }\r
 \r
       return true;\r
-\r
     }\r
 \r
+    void parseDescriptionHTML(SequenceFeature sf, boolean removeHTML)\r
+    {\r
+      StringBuffer sb = new StringBuffer();\r
+      StringTokenizer st = new StringTokenizer(sf.getDescription(), "<");\r
+      String token,  link;\r
+      while(st.hasMoreElements())\r
+      {\r
+        token = st.nextToken("<>");\r
+        if(token.equalsIgnoreCase("html") || token.startsWith("/"))\r
+          continue;\r
+\r
+        if(token.startsWith("a href="))\r
+        {\r
+          link = token.substring(token.indexOf("\"")+1, token.length()-1);\r
+          String label = st.nextToken("<>");\r
+          sf.addLink(label+"|"+link);\r
+          sb.append(label+"%LINK%");\r
+        }\r
+        else if(token.equalsIgnoreCase("br"))\r
+          sb.append("\n");\r
+        else\r
+          sb.append(token);\r
+      }\r
+\r
+      if(removeHTML)\r
+        sf.description = sb.toString();\r
+  }\r
 \r
     /**\r
      * DOCUMENT ME!\r
@@ -278,12 +350,15 @@ public class FeaturesFile extends AlignFile
 \r
         do\r
         {\r
-          if (groups.size() > 0)\r
+\r
+\r
+          if (groups.size() > 0 && groupIndex < groups.size())\r
           {\r
             group = groups.elementAt(groupIndex).toString();\r
             out.append("\nSTARTGROUP\t" + group + "\n");\r
           }\r
-\r
+          else\r
+            group = null;\r
 \r
           for (int i = 0; i < seqs.length; i++)\r
           {\r
@@ -295,13 +370,41 @@ public class FeaturesFile extends AlignFile
                 if (!visible.containsKey(next[j].type))\r
                   continue;\r
 \r
-                if (group != null && !next[j].featureGroup.equals(group))\r
+                if (group != null\r
+                    && (next[j].featureGroup==null\r
+                        || !next[j].featureGroup.equals(group))\r
+                  )\r
+                  continue;\r
+\r
+                if(group==null && next[j].featureGroup!=null)\r
                   continue;\r
 \r
                 if(next[j].description==null || next[j].description.equals(""))\r
                   out.append(next[j].type+"\t");\r
                 else\r
-                  out.append(next[j].description + "\t");\r
+                {\r
+                  out.append(next[j].description+" ");\r
+                  if(next[j].links!=null)\r
+                    {\r
+                      for(int l=0; l<next[j].links.size(); l++)\r
+                      {\r
+                        String label = next[j].links.elementAt(l).toString();\r
+                        String href = label.substring(label.indexOf("|")+1);\r
+                        label = label.substring(0, label.indexOf("|"));\r
+\r
+                        if(next[j].description.indexOf(href)==-1)\r
+                        {\r
+                          out.append("<a href=\""\r
+                                     + href\r
+                                     + "\">"\r
+                                     + label\r
+                                     + "</a>");\r
+                        }\r
+                      }\r
+                    }\r
+                   out.append("\t");\r
+                }\r
+\r
 \r
                 out.append(  seqs[i].getName() + "\t-1\t"\r
                            + next[j].begin + "\t"\r
@@ -312,14 +415,16 @@ public class FeaturesFile extends AlignFile
             }\r
           }\r
 \r
-          if(groups.size()>0)\r
+          if(group!=null)\r
           {\r
             out.append("ENDGROUP\t"+group+"\n");\r
+            groupIndex++;\r
           }\r
+          else\r
+            break;\r
 \r
-          groupIndex++;\r
         }\r
-        while(groupIndex < groups.size());\r
+        while(groupIndex < groups.size()+1);\r
 \r
 \r
       return out.toString();\r
@@ -329,6 +434,7 @@ public class FeaturesFile extends AlignFile
     {\r
       StringBuffer out = new StringBuffer();\r
       SequenceFeature [] next;\r
+      String source;\r
 \r
       for(int i=0; i<seqs.length; i++)\r
       {\r
@@ -340,8 +446,12 @@ public class FeaturesFile extends AlignFile
             if(!visible.containsKey(next[j].type))\r
               continue;\r
 \r
+            source = next[j].featureGroup;\r
+            if(source==null)\r
+              source = next[j].getDescription();\r
+\r
             out.append(seqs[i].getName() + "\t"\r
-                       + next[j].description + "\t"\r
+                       + source + "\t"\r
                        + next[j].type  + "\t"\r
                        + next[j].begin + "\t"\r
                        + next[j].end   + "\t"\r
@@ -352,10 +462,16 @@ public class FeaturesFile extends AlignFile
               out.append(next[j].getValue("STRAND")+"\t");\r
             else\r
               out.append(".\t");\r
+\r
             if(next[j].getValue("FRAME")!=null)\r
-              out.append(next[j].getValue("FRAME")+"\n");\r
+              out.append(next[j].getValue("FRAME"));\r
             else\r
-              out.append(".\n");\r
+              out.append(".");\r
+\r
+            if(next[j].getValue("ATTRIBUTES")!=null)\r
+              out.append(next[j].getValue("ATTRIBUTES"));\r
+\r
+            out.append("\n");\r
 \r
           }\r
         }\r