Working links menu
[jalview.git] / src / jalview / util / UrlLink.java
index 2936ac3..a8c0b32 100644 (file)
@@ -1,23 +1,28 @@
 /*
- * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.1)
- * Copyright (C) 2014 The Jalview Authors
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
  * 
  * This file is part of Jalview.
  * 
  * Jalview is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License 
- * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
  *  
  * Jalview is distributed in the hope that it will be useful, but 
  * WITHOUT ANY WARRANTY; without even the implied warranty 
  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
  * PURPOSE.  See the GNU General Public License for more details.
  * 
- * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
  * The Jalview Authors are detailed in the 'AUTHORS' file.
  */
 package jalview.util;
 
+import static jalview.util.UrlConstants.SEQUENCE_ID;
+import static jalview.util.UrlConstants.SEQUENCE_NAME;
+
 import java.util.Vector;
 
 public class UrlLink
@@ -35,6 +40,8 @@ public class UrlLink
 
   private boolean dynamic = false;
 
+  private boolean uses_seq_id = false;
+
   private String invalidMessage = null;
 
   /**
@@ -46,36 +53,20 @@ public class UrlLink
    */
   public UrlLink(String link)
   {
-    int sep = link.indexOf("|"), psqid = link.indexOf("$SEQUENCE_ID");
+    int sep = link.indexOf("|");
+    int psqid = link.indexOf("$" + SEQUENCE_ID);
+    int nsqid = link.indexOf("$" + SEQUENCE_NAME);
     if (psqid > -1)
     {
       dynamic = true;
-      int p = sep;
-      do
-      {
-        sep = p;
-        p = link.indexOf("|", sep + 1);
-      } while (p > sep && p < psqid);
-      // Assuming that the URL itself does not contain any '|' symbols
-      // sep now contains last pipe symbol position prior to any regex symbols
-      label = link.substring(0, sep);
-      if (label.indexOf("|") > -1)
-      {
-        // | terminated database name / www target at start of Label
-        target = label.substring(0, label.indexOf("|"));
-      }
-      else if (label.indexOf(" ") > 2)
-      {
-        // space separated Label - matches database name
-        target = label.substring(0, label.indexOf(" "));
-      }
-      else
-      {
-        target = label;
-      }
+      uses_seq_id = true;
+
+      sep = parseTargetAndLabel(sep, psqid, link);
+
       // Parse URL : Whole URL string first
+      int p;
       url_prefix = link.substring(sep + 1, psqid);
-      if (link.indexOf("$SEQUENCE_ID=/") == psqid
+      if (link.indexOf("$" + SEQUENCE_ID + "=/") == psqid
               && (p = link.indexOf("/=$", psqid + 14)) > psqid + 14)
       {
         // Extract Regex and suffix
@@ -100,7 +91,7 @@ public class UrlLink
       {
         regexReplace = null;
         // verify format is really correct.
-        if (link.indexOf("$SEQUENCE_ID$") == psqid)
+        if (link.indexOf("$" + SEQUENCE_ID + "$") == psqid)
         {
           url_suffix = link.substring(psqid + 13);
           regexReplace = null;
@@ -112,6 +103,50 @@ public class UrlLink
         }
       }
     }
+    else if (nsqid > -1)
+    {
+      dynamic = true;
+      sep = parseTargetAndLabel(sep, nsqid, link);
+
+      int p;
+      url_prefix = link.substring(sep + 1, nsqid);
+      if (link.indexOf("$" + SEQUENCE_NAME + "=/") == nsqid
+              && (p = link.indexOf("/=$", nsqid + 16)) > nsqid + 16)
+      {
+        // Extract Regex and suffix
+        url_suffix = link.substring(p + 3);
+        regexReplace = link.substring(nsqid + 16, p);
+        try
+        {
+          com.stevesoft.pat.Regex rg = com.stevesoft.pat.Regex.perlCode("/"
+                  + regexReplace + "/");
+          if (rg == null)
+          {
+            invalidMessage = "Invalid Regular Expression : '"
+                    + regexReplace + "'\n";
+          }
+        } catch (Exception e)
+        {
+          invalidMessage = "Invalid Regular Expression : '" + regexReplace
+                  + "'\n";
+        }
+      }
+      else
+      {
+        regexReplace = null;
+        // verify format is really correct.
+        if (link.indexOf("$" + SEQUENCE_NAME + "$") == nsqid)
+        {
+          url_suffix = link.substring(nsqid + 15);
+          regexReplace = null;
+        }
+        else
+        {
+          invalidMessage = "Warning: invalid regex structure for URL link : "
+                  + link;
+        }
+      }
+    }
     else
     {
       target = link.substring(0, sep);
@@ -206,8 +241,7 @@ public class UrlLink
           if (ns == 0)
           {
             // take whole regex
-            return new String[]
-            { rg.stringMatched(),
+            return new String[] { rg.stringMatched(),
                 url_prefix + rg.stringMatched() + url_suffix };
           } /*
              * else if (ns==1) { // take only subgroup match return new String[]
@@ -286,27 +320,54 @@ public class UrlLink
       }
 
       // just return simple url substitution.
-      return new String[]
-      { idstring, url_prefix + idstring + url_suffix };
+      return new String[] { idstring, url_prefix + idstring + url_suffix };
     }
     else
     {
-      return new String[]
-      { "", url_prefix };
+      return new String[] { "", url_prefix };
     }
   }
 
+  @Override
   public String toString()
   {
     return label
             + "|"
             + url_prefix
-            + (dynamic ? ("$SEQUENCE_ID" + ((regexReplace != null) ? "="
+            + (dynamic ? ("$" + SEQUENCE_ID + ((regexReplace != null) ? "="
                     + regexReplace + "=$" : "$")) : "")
             + ((url_suffix == null) ? "" : url_suffix);
 
   }
 
+  private int parseTargetAndLabel(int sep, int psqid, String link)
+  {
+    int p = sep;
+    do
+    {
+      sep = p;
+      p = link.indexOf("|", sep + 1);
+    } while (p > sep && p < psqid);
+    // Assuming that the URL itself does not contain any '|' symbols
+    // sep now contains last pipe symbol position prior to any regex symbols
+    label = link.substring(0, sep);
+    if (label.indexOf("|") > -1)
+    {
+      // | terminated database name / www target at start of Label
+      target = label.substring(0, label.indexOf("|"));
+    }
+    else if (label.indexOf(" ") > 2)
+    {
+      // space separated Label - matches database name
+      target = label.substring(0, label.indexOf(" "));
+    }
+    else
+    {
+      target = label;
+    }
+    return sep;
+  }
+
   private static void testUrls(UrlLink ul, String idstring, String[] urls)
   {
 
@@ -327,8 +388,7 @@ public class UrlLink
 
   public static void main(String argv[])
   {
-    String[] links = new String[]
-    {
+    String[] links = new String[] {
     /*
      * "AlinkT|Target|http://foo.foo.soo/",
      * "myUrl1|http://$SEQUENCE_ID=/[0-9]+/=$.someserver.org/foo",
@@ -343,9 +403,9 @@ public class UrlLink
      * "PF3|http://us.expasy.org/cgi-bin/niceprot.pl?$SEQUENCE_ID=/PFAM:(.+)/=$"
      * , "NOTFER|http://notfer.org/$SEQUENCE_ID=/(?<!\\s)(.+)/=$",
      */
-    "NESTED|http://nested/$SEQUENCE_ID=/^(?:Label:)?(?:(?:gi\\|(\\d+))|([^:]+))/=$/nested" };
-    String[] idstrings = new String[]
-    {
+    "NESTED|http://nested/$" + SEQUENCE_ID
+            + "=/^(?:Label:)?(?:(?:gi\\|(\\d+))|([^:]+))/=$/nested" };
+    String[] idstrings = new String[] {
     /*
      * //"LGUL_human", //"QWIQW_123123", "uniprot|why_do+_12313_foo",
      * //"123123312", "123123 ABCDE foo", "PFAM:PF23943",
@@ -392,6 +452,11 @@ public class UrlLink
     return dynamic;
   }
 
+  public boolean usesSeqId()
+  {
+    return uses_seq_id;
+  }
+
   public void setLabel(String newlabel)
   {
     this.label = newlabel;