JAL-2316 Moved url providers into own package
[jalview.git] / src / jalview / urls / CustomUrlProvider.java
diff --git a/src/jalview/urls/CustomUrlProvider.java b/src/jalview/urls/CustomUrlProvider.java
new file mode 100644 (file)
index 0000000..50037b6
--- /dev/null
@@ -0,0 +1,266 @@
+/*
+ * 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.
+ *  
+ * 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/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+
+package jalview.urls;
+
+//import static jalview.util.UrlConstants.EMBLEBI_LABEL;
+//import static jalview.util.UrlConstants.EMBLEBI_STRING;
+//import static jalview.util.UrlConstants.SRS_LABEL;
+
+
+import static jalview.util.UrlConstants.DB_ACCESSION;
+import static jalview.util.UrlConstants.DELIM;
+import static jalview.util.UrlConstants.SEP;
+import static jalview.util.UrlConstants.SEQUENCE_ID;
+
+import jalview.util.MessageManager;
+import jalview.util.UrlLink;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+/**
+ * 
+ * Implements the UrlProviderI interface for a UrlProvider object which serves
+ * custom URLs defined by the user
+ * 
+ * @author $author$
+ * @version $Revision$
+ */
+public class CustomUrlProvider extends UrlProviderImpl
+{
+
+  // minimum length of substitution in url link string
+  private static final int MIN_SUBST_LENGTH = 4;
+
+  // 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;
+
+  /**
+   * Construct UrlProvider for custom (user-entered) URLs
+   * 
+   * @param cachedUrlList
+   *          list of URLs in form stored in Cache. i.e. SEP delimited string
+   */
+  public CustomUrlProvider(String cachedUrlList)
+  {
+    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();
+        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)
+        {
+          url = url + SEP + st.nextToken();
+        }
+        urls.put(name, new UrlLink(name + SEP + url));
+      }
+    } catch (Exception ex)
+    {
+      System.out.println(ex + "\nError parsing sequence links");
+    }
+    upgradeOldLinks();
+
+  }
+
+  /**
+   * Construct UrlProvider for custom (user-entered) URLs
+   * 
+   * @param urlList
+   *          list of URLs as (label,url) pairs
+   */
+  public CustomUrlProvider(Map<String, String> urlList)
+  {
+    try
+    {
+      urls = new HashMap<String, UrlLink>();
+      Iterator<Map.Entry<String, String>> it = urlList.entrySet()
+              .iterator();
+      while (it.hasNext())
+      {
+        Map.Entry<String, String> pair = it.next();
+        urls.put(pair.getKey(),
+                new UrlLink(pair.getKey() + SEP + pair.getValue()));
+      }
+    } catch (Exception ex)
+    {
+      System.out.println(ex + "\nError parsing sequence links");
+    }
+    upgradeOldLinks();
+  }
+
+  /*
+   * Upgrade any legacy links which may have been left lying around
+   */
+  private void upgradeOldLinks()
+  {
+    // upgrade old SRS link
+    if (urls.containsKey(SRS_LABEL))
+    {
+      urls.remove(SRS_LABEL);
+      urls.put(DEFAULT_LABEL, new UrlLink(DEFAULT_STRING));
+    }
+  }
+
+  @Override
+  public Vector<String> getLinksForDisplay()
+  {
+    Vector<String> links = new Vector<String>();
+    Iterator<Map.Entry<String, UrlLink>> it = urls.entrySet().iterator();
+    while (it.hasNext())
+    {
+      Map.Entry<String, UrlLink> pair = it.next();
+      links.add(pair.getValue().toString());
+    }
+    return links;
+  }
+
+  @Override
+  public boolean setDefaultUrl(String id)
+  {
+    if (urls.containsKey(id))
+    {
+      defaultUrl = id;
+    }
+    else
+    {
+      defaultUrl = null;
+    }
+    return urls.containsKey(id);
+  }
+
+  @Override
+  public String writeUrlsAsString()
+  {
+    StringBuffer links = new StringBuffer();
+    if (urls.size() > 0)
+    {
+      for (UrlLink link : urls.values())
+      {
+        links.append(link.toString());
+        links.append(SEP);
+      }
+
+      // remove last SEP
+      links.setLength(links.length() - 1);
+    }
+    else
+    {
+      urls.clear();
+    }
+    return links.toString();
+  }
+
+  @Override
+  public String getDefaultUrl(String seqid)
+  {
+    if (defaultUrl == null)
+    {
+      return null;
+    }
+
+    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 getDefaultTarget(String seqid)
+  {
+    return urls.get(defaultUrl).getTarget();
+  }
+
+  @Override
+  public void setUrlLinks(Vector<String> names, Vector<String> urlstrings)
+  {
+    HashMap<String, UrlLink> newurls = new HashMap<String, UrlLink>();
+
+    // should check that lists are same length but this function is likely
+    // to change once the Preferences dialog is rebuilt
+
+    for (int i = 0; i < names.size(); ++i)
+    {
+      // don't allow MIRIAM ids as custom url names (as the links will overwrite
+      // each other)
+      // unlikely user would try to do this, but...
+      if (isMiriamId(names.elementAt(i)))
+      {
+        throw new IllegalArgumentException(MessageManager.formatMessage(
+                "exception.url_cannot_have_miriam_id", names.elementAt(i)));
+      }
+      // don't allow duplicate key names as entries will be overwritten
+      if (newurls.containsKey(names.elementAt(i)))
+      {
+        throw new IllegalArgumentException(MessageManager.formatMessage(
+                "exception.url_cannot_have_duplicate_id",
+                names.elementAt(i)));
+      }
+      newurls.put(names.elementAt(i), new UrlLink(names.elementAt(i) + SEP
+              + urlstrings.elementAt(i)));
+    }
+
+    // don't update until we're sure this set is ok
+    urls = newurls;
+
+  }
+
+  @Override
+  public String chooseDefaultUrl()
+  {
+    // unilaterally set the default id to the EMBL_EBI link
+    
+    if (!urls.containsKey(DEFAULT_LABEL))
+    {
+      urls.put(DEFAULT_LABEL, new UrlLink(DEFAULT_STRING));
+    }
+    return DEFAULT_LABEL;
+  }
+
+}