JAL-2069 update spike branch with latest
[jalview.git] / src / jalview / urls / CustomUrlProvider.java
index a178ed6..86d5660 100644 (file)
@@ -37,7 +37,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.StringTokenizer;
-import java.util.Vector;
 
 /**
  * 
@@ -52,98 +51,145 @@ public class CustomUrlProvider extends UrlProviderImpl
   // Default sequence URL link label for SRS
   private static final String SRS_LABEL = "SRS";
 
-  // map of string ids to urlLinks
-  private HashMap<String, UrlLink> urls;
+  // map of string ids to urlLinks (selected)
+  private HashMap<String, UrlLink> selectedUrls;
+
+  // map of string ids to urlLinks (not selected)
+  private HashMap<String, UrlLink> nonselectedUrls;
 
   /**
    * Construct UrlProvider for custom (user-entered) URLs
    * 
-   * @param cachedUrlList
-   *          list of URLs in form stored in Cache. i.e. SEP delimited string
+   * @param inMenuUrlList
+   *          list of URLs set to be displayed in menu, in form stored in Cache.
+   *          i.e. SEP delimited string
+   * @param storedUrlList
+   *          list of custom URLs entered by user but not currently displayed in
+   *          menu, in form stored in Cache
    */
-  public CustomUrlProvider(String cachedUrlList)
+  public CustomUrlProvider(String inMenuUrlList, String storedUrlList)
   {
     try
     {
-      urls = new HashMap<String, UrlLink>();
-
-      // cachedUrlList is in form <label>|<url>|<label>|<url>...
-      // parse cachedUrlList into labels (used as id) and url links
-      StringTokenizer st = new StringTokenizer(cachedUrlList, SEP);
-      while (st.hasMoreElements())
-      {
-        String name = st.nextToken();
-
-        if (!isMiriamId(name))
-        {
-          // this one of our custom urls
-          String url = st.nextToken();
-          // check for '|' within a regex
-          int rxstart = url.indexOf(DELIM + DB_ACCESSION + DELIM);
-          if (rxstart == -1)
-          {
-            rxstart = url.indexOf(DELIM + SEQUENCE_ID + DELIM);
-          }
-          while (rxstart == -1 && url.indexOf("/=" + DELIM) == -1
-                  && st.hasMoreTokens())
-          {
-            url = url + SEP + st.nextToken();
-          }
-          urls.put(name, new UrlLink(name + SEP + url));
-        }
-      }
+      selectedUrls = parseUrlStrings(inMenuUrlList);
+      nonselectedUrls = parseUrlStrings(storedUrlList);
     } catch (Exception ex)
     {
-      System.out.println(ex + "\nError parsing sequence links");
+      System.out
+              .println(ex.getMessage() + "\nError parsing sequence links");
     }
-    upgradeOldLinks();
-
   }
 
   /**
    * Construct UrlProvider for custom (user-entered) URLs
    * 
    * @param urlList
-   *          list of URLs as (label,url) pairs
+   *          list of URLs to be displayed in menu, as (label,url) pairs
+   * @param storedUrlList
+   *          list of custom URLs entered by user but not currently displayed in
+   *          menu, as (label,url) pairs
    */
-  public CustomUrlProvider(Map<String, String> urlList)
+  public CustomUrlProvider(Map<String, String> inMenuUrlList,
+          Map<String, String> storedUrlList)
   {
     try
     {
-      urls = new HashMap<String, UrlLink>();
-      Iterator<Map.Entry<String, String>> it = urlList.entrySet()
-              .iterator();
-      while (it.hasNext())
+      selectedUrls = parseUrlList(inMenuUrlList);
+      nonselectedUrls = parseUrlList(storedUrlList);
+    } catch (Exception ex)
+    {
+      System.out
+              .println(ex.getMessage() + "\nError parsing sequence links");
+    }
+  }
+
+  private HashMap<String, UrlLink> parseUrlStrings(String urlStrings)
+  {
+    // cachedUrlList is in form <label>|<url>|<label>|<url>...
+    // parse cachedUrlList into labels (used as id) and url links
+    HashMap<String, UrlLink> urls = new HashMap<String, UrlLink>();
+
+    StringTokenizer st = new StringTokenizer(urlStrings, SEP);
+    while (st.hasMoreElements())
+    {
+      String name = st.nextToken();
+
+      if (!isMiriamId(name))
       {
-        Map.Entry<String, String> pair = it.next();
-        urls.put(pair.getKey(),
-                new UrlLink(pair.getKey() + SEP + pair.getValue()));
+        // this one of our custom urls
+        String url = st.nextToken();
+        // check for '|' within a regex
+        int rxstart = url.indexOf(DELIM + DB_ACCESSION + DELIM);
+        if (rxstart == -1)
+        {
+          rxstart = url.indexOf(DELIM + SEQUENCE_ID + DELIM);
+        }
+        while (rxstart == -1 && url.indexOf("/=" + DELIM) == -1
+                && st.hasMoreTokens())
+        {
+          url = url + SEP + st.nextToken();
+        }
+        urls.put(name, new UrlLink(name, url, name));
       }
-    } catch (Exception ex)
+    }
+    upgradeOldLinks(urls);
+    return urls;
+  }
+
+  private HashMap<String, UrlLink> parseUrlList(Map<String, String> urlList)
+  {
+    HashMap<String, UrlLink> urls = new HashMap<String, UrlLink>();
+    if (urlList == null)
+    {
+      return urls;
+    }
+
+    Iterator<Map.Entry<String, String>> it = urlList.entrySet().iterator();
+    while (it.hasNext())
     {
-      System.out.println(ex + "\nError parsing sequence links");
+      Map.Entry<String, String> pair = it.next();
+      urls.put(pair.getKey(),
+              new UrlLink(pair.getKey(), pair.getValue(), pair.getKey()));
     }
-    upgradeOldLinks();
+    upgradeOldLinks(urls);
+    return urls;
   }
 
   /*
    * Upgrade any legacy links which may have been left lying around
    */
-  private void upgradeOldLinks()
+  private void upgradeOldLinks(HashMap<String, UrlLink> urls)
   {
+    boolean upgrade = false;
     // upgrade old SRS link
     if (urls.containsKey(SRS_LABEL))
     {
       urls.remove(SRS_LABEL);
-      urls.put(UrlConstants.DEFAULT_LABEL, new UrlLink(UrlConstants.DEFAULT_STRING));
+      upgrade = true;
+    }
+    // upgrade old EBI link - easier just to remove and re-add than faffing
+    // around checking exact url
+    if (urls.containsKey(UrlConstants.DEFAULT_LABEL))
+    {
+      // note because this is called separately for selected and nonselected
+      // urls, the default url will not always be present
+      urls.remove(UrlConstants.DEFAULT_LABEL);
+      upgrade = true;
+    }
+    if (upgrade)
+    {
+      UrlLink link = new UrlLink(UrlConstants.DEFAULT_STRING);
+      link.setLabel(UrlConstants.DEFAULT_LABEL);
+      urls.put(UrlConstants.DEFAULT_LABEL, link);
     }
   }
 
   @Override
-  public Vector<String> getLinksForMenu()
+  public List<String> getLinksForMenu()
   {
-    Vector<String> links = new Vector<String>();
-    Iterator<Map.Entry<String, UrlLink>> it = urls.entrySet().iterator();
+    List<String> links = new ArrayList<String>();
+    Iterator<Map.Entry<String, UrlLink>> it = selectedUrls.entrySet()
+            .iterator();
     while (it.hasNext())
     {
       Map.Entry<String, UrlLink> pair = it.next();
@@ -156,46 +202,54 @@ public class CustomUrlProvider extends UrlProviderImpl
   public List<UrlLinkDisplay> getLinksForTable()
   {
     ArrayList<UrlLinkDisplay> displayLinks = new ArrayList<UrlLinkDisplay>();
-    for (Entry<String, UrlLink> entry : urls.entrySet())
-    {
-      String key = entry.getKey();
-      boolean isDefault = (key.equals(defaultUrl));
-      boolean isSelected = true; // custom urls always selected
-      String displayLink = entry.getValue().toString().split("\\|")[1]; // TODO
-                                                                        // sort
-                                                                        // this
-                                                                        // out
-                                                                        // properly!
-      displayLinks.add(new UrlLinkDisplay(key, key, displayLink,
-              isSelected,
-              isDefault));
-    }
+    displayLinks = getLinksForTable(selectedUrls, true);
+    displayLinks.addAll(getLinksForTable(nonselectedUrls, false));
     return displayLinks;
   }
 
+  private ArrayList<UrlLinkDisplay> getLinksForTable(
+          HashMap<String, UrlLink> urlList, boolean selected)
+  {
+    return super.getLinksForTable(urlList, null, selected);
+  }
+
   @Override
-  public boolean setDefaultUrl(String id)
+  public boolean setPrimaryUrl(String id)
   {
-    if (urls.containsKey(id))
+    if (selectedUrls.containsKey(id))
+    {
+      primaryUrl = id;
+    }
+    else if (nonselectedUrls.containsKey(id))
     {
-      defaultUrl = id;
+      primaryUrl = id;
     }
     else
     {
-      defaultUrl = null;
+      primaryUrl = null;
     }
-    return urls.containsKey(id);
+
+    return (primaryUrl != null);
   }
 
   @Override
-  public String writeUrlsAsString()
+  public String writeUrlsAsString(boolean selected)
   {
     StringBuffer links = new StringBuffer();
+    HashMap<String, UrlLink> urls;
+    if (selected)
+    {
+      urls = selectedUrls;
+    }
+    else
+    {
+      urls = nonselectedUrls;
+    }
     if (urls.size() > 0)
     {
-      for (UrlLink link : urls.values())
+      for (Entry<String, UrlLink> entry : urls.entrySet())
       {
-        links.append(link.toString());
+        links.append(entry.getValue().toString());
         links.append(SEP);
       }
 
@@ -210,39 +264,33 @@ public class CustomUrlProvider extends UrlProviderImpl
   }
 
   @Override
-  public String getDefaultUrl(String seqid)
+  public String getPrimaryUrl(String seqid)
   {
-    if (defaultUrl == null)
+    String result = super.getPrimaryUrl(seqid, selectedUrls);
+    if (result == null)
     {
-      return null;
+      result = super.getPrimaryUrl(seqid, nonselectedUrls);
     }
+    return result;
+  }
 
-    String url = null;
-    UrlLink urlLink = urls.get(defaultUrl);
-    String[] defaultUrls = urlLink.makeUrls(seqid, true);
-    if (defaultUrls == null || defaultUrls[0] == null
-            || defaultUrls[0].length() < MIN_SUBST_LENGTH)
-    {
-      url = null;
-    }
-    else
-    {
-      // just take first URL made from regex
-      url = defaultUrls[1];
-    }
-    return url;
+  @Override
+  public String getPrimaryUrlId()
+  {
+    return primaryUrl;
   }
 
   @Override
-  public String getDefaultTarget(String seqid)
+  public String getPrimaryTarget(String seqid)
   {
-    return urls.get(defaultUrl).getTarget();
+    return selectedUrls.get(primaryUrl).getTarget();
   }
 
   @Override
   public void setUrlData(List<UrlLinkDisplay> links)
   {
-    HashMap<String, UrlLink> newurls = new HashMap<String, UrlLink>();
+    HashMap<String, UrlLink> unselurls = new HashMap<String, UrlLink>();
+    HashMap<String, UrlLink> selurls = new HashMap<String, UrlLink>();
 
     Iterator<UrlLinkDisplay> it = links.iterator();
     while (it.hasNext())
@@ -252,43 +300,55 @@ public class CustomUrlProvider extends UrlProviderImpl
       // MIRIAM ids will be handled by a different UrlProvider class
       if (!isMiriamId(link.getId()))
       {
-
         // don't allow duplicate key names as entries will be overwritten
-        if (newurls.containsKey(link.getId()))
+        if (unselurls.containsKey(link.getId())
+                || selurls.containsKey(link.getId()))
         {
           throw new IllegalArgumentException(MessageManager.formatMessage(
                   "exception.url_cannot_have_duplicate_id", link.getId()));
         }
         if (link.getIsSelected())
         {
-          newurls.put(link.getId(),
-                  new UrlLink(link.getId() + SEP + link.getUrl()));
-
-          // sort out default and selected ids
-          if (link.getIsDefault())
-          {
-            setDefaultUrl(link.getId());
-          }
+          selurls.put(link.getId(), new UrlLink(link.getDescription(),
+                  link.getUrl(), link.getDescription()));
+        }
+        else
+        {
+          unselurls.put(link.getId(), new UrlLink(link.getDescription(),
+                  link.getUrl(), link.getDescription()));
+        }
+        // sort out primary and selected ids
+        if (link.getIsPrimary())
+        {
+          setPrimaryUrl(link.getId());
         }
-          // TODO KM make it possible to set and save selected custom urls
-
       }
 
     }
-    urls = newurls;
+    nonselectedUrls = unselurls;
+    selectedUrls = selurls;
   }
 
   @Override
-  public String chooseDefaultUrl()
+  public String choosePrimaryUrl()
   {
-    // unilaterally set the default id to the EMBL_EBI link
-    
-    if (!urls.containsKey(UrlConstants.DEFAULT_LABEL))
+    // unilaterally set the primary id to the EMBL_EBI link
+    if ((!nonselectedUrls.containsKey(UrlConstants.DEFAULT_LABEL))
+            && (!selectedUrls.containsKey(UrlConstants.DEFAULT_LABEL)))
     {
-      urls.put(UrlConstants.DEFAULT_LABEL, new UrlLink(UrlConstants.DEFAULT_STRING));
+      UrlLink link = new UrlLink(UrlConstants.DEFAULT_STRING);
+      link.setLabel(UrlConstants.DEFAULT_LABEL);
+      selectedUrls.put(UrlConstants.DEFAULT_LABEL, link);
     }
-    defaultUrl = UrlConstants.DEFAULT_LABEL;
+    primaryUrl = UrlConstants.DEFAULT_LABEL;
     return UrlConstants.DEFAULT_LABEL;
   }
 
+  @Override
+  public boolean contains(String id)
+  {
+    return (selectedUrls.containsKey(id)
+            || nonselectedUrls.containsKey(id));
+  }
+
 }