JAL-2316 First pass identifiers.org downloading working
[jalview.git] / src / jalview / urls / CustomUrlProvider.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21
22 package jalview.urls;
23
24 import static jalview.util.UrlConstants.DB_ACCESSION;
25 import static jalview.util.UrlConstants.DELIM;
26 import static jalview.util.UrlConstants.SEP;
27 import static jalview.util.UrlConstants.SEQUENCE_ID;
28
29 import jalview.util.MessageManager;
30 import jalview.util.UrlLink;
31
32 import java.util.HashMap;
33 import java.util.Iterator;
34 import java.util.Map;
35 import java.util.StringTokenizer;
36 import java.util.Vector;
37
38 /**
39  * 
40  * Implements the UrlProviderI interface for a UrlProvider object which serves
41  * custom URLs defined by the user
42  * 
43  * @author $author$
44  * @version $Revision$
45  */
46 public class CustomUrlProvider extends UrlProviderImpl
47 {
48
49   // minimum length of substitution in url link string
50   private static final int MIN_SUBST_LENGTH = 4;
51
52   // Default sequence URL link label for SRS
53   private static final String SRS_LABEL = "SRS";
54
55   // map of string ids to urlLinks
56   private HashMap<String, UrlLink> urls;
57
58   /**
59    * Construct UrlProvider for custom (user-entered) URLs
60    * 
61    * @param cachedUrlList
62    *          list of URLs in form stored in Cache. i.e. SEP delimited string
63    */
64   public CustomUrlProvider(String cachedUrlList)
65   {
66     try
67     {
68       urls = new HashMap<String, UrlLink>();
69
70       // cachedUrlList is in form <label>|<url>|<label>|<url>...
71       // parse cachedUrlList into labels (used as id) and url links
72       StringTokenizer st = new StringTokenizer(cachedUrlList, SEP);
73       while (st.hasMoreElements())
74       {
75         String name = st.nextToken();
76         String url = st.nextToken();
77         // check for '|' within a regex
78         int rxstart = url.indexOf(DELIM + DB_ACCESSION + DELIM);
79         if (rxstart == -1)
80         {
81           rxstart = url.indexOf(DELIM + SEQUENCE_ID + DELIM);
82         }
83         while (rxstart == -1 && url.indexOf("/=" + DELIM) == -1
84                 && st.hasMoreTokens())
85         {
86           url = url + SEP + st.nextToken();
87         }
88         urls.put(name, new UrlLink(name + SEP + url));
89       }
90     } catch (Exception ex)
91     {
92       System.out.println(ex + "\nError parsing sequence links");
93     }
94     upgradeOldLinks();
95
96   }
97
98   /**
99    * Construct UrlProvider for custom (user-entered) URLs
100    * 
101    * @param urlList
102    *          list of URLs as (label,url) pairs
103    */
104   public CustomUrlProvider(Map<String, String> urlList)
105   {
106     try
107     {
108       urls = new HashMap<String, UrlLink>();
109       Iterator<Map.Entry<String, String>> it = urlList.entrySet()
110               .iterator();
111       while (it.hasNext())
112       {
113         Map.Entry<String, String> pair = it.next();
114         urls.put(pair.getKey(),
115                 new UrlLink(pair.getKey() + SEP + pair.getValue()));
116       }
117     } catch (Exception ex)
118     {
119       System.out.println(ex + "\nError parsing sequence links");
120     }
121     upgradeOldLinks();
122   }
123
124   /*
125    * Upgrade any legacy links which may have been left lying around
126    */
127   private void upgradeOldLinks()
128   {
129     // upgrade old SRS link
130     if (urls.containsKey(SRS_LABEL))
131     {
132       urls.remove(SRS_LABEL);
133       urls.put(DEFAULT_LABEL, new UrlLink(DEFAULT_STRING));
134     }
135   }
136
137   @Override
138   public Vector<String> getLinksForDisplay()
139   {
140     Vector<String> links = new Vector<String>();
141     Iterator<Map.Entry<String, UrlLink>> it = urls.entrySet().iterator();
142     while (it.hasNext())
143     {
144       Map.Entry<String, UrlLink> pair = it.next();
145       links.add(pair.getValue().toString());
146     }
147     return links;
148   }
149
150   @Override
151   public boolean setDefaultUrl(String id)
152   {
153     if (urls.containsKey(id))
154     {
155       defaultUrl = id;
156     }
157     else
158     {
159       defaultUrl = null;
160     }
161     return urls.containsKey(id);
162   }
163
164   @Override
165   public String writeUrlsAsString()
166   {
167     StringBuffer links = new StringBuffer();
168     if (urls.size() > 0)
169     {
170       for (UrlLink link : urls.values())
171       {
172         links.append(link.toString());
173         links.append(SEP);
174       }
175
176       // remove last SEP
177       links.setLength(links.length() - 1);
178     }
179     else
180     {
181       urls.clear();
182     }
183     return links.toString();
184   }
185
186   @Override
187   public String getDefaultUrl(String seqid)
188   {
189     if (defaultUrl == null)
190     {
191       return null;
192     }
193
194     String url = null;
195     UrlLink urlLink = urls.get(defaultUrl);
196     String[] defaultUrls = urlLink.makeUrls(seqid, true);
197     if (defaultUrls == null || defaultUrls[0] == null
198             || defaultUrls[0].length() < MIN_SUBST_LENGTH)
199     {
200       url = null;
201     }
202     else
203     {
204       // just take first URL made from regex
205       url = defaultUrls[1];
206     }
207     return url;
208   }
209
210   @Override
211   public String getDefaultTarget(String seqid)
212   {
213     return urls.get(defaultUrl).getTarget();
214   }
215
216   @Override
217   public void setUrlLinks(Vector<String> names, Vector<String> urlstrings)
218   {
219     HashMap<String, UrlLink> newurls = new HashMap<String, UrlLink>();
220
221     // should check that lists are same length but this function is likely
222     // to change once the Preferences dialog is rebuilt
223
224     for (int i = 0; i < names.size(); ++i)
225     {
226       // don't allow MIRIAM ids as custom url names (as the links will overwrite
227       // each other)
228       // unlikely user would try to do this, but...
229       if (isMiriamId(names.elementAt(i)))
230       {
231         throw new IllegalArgumentException(MessageManager.formatMessage(
232                 "exception.url_cannot_have_miriam_id", names.elementAt(i)));
233       }
234       // don't allow duplicate key names as entries will be overwritten
235       if (newurls.containsKey(names.elementAt(i)))
236       {
237         throw new IllegalArgumentException(MessageManager.formatMessage(
238                 "exception.url_cannot_have_duplicate_id",
239                 names.elementAt(i)));
240       }
241       newurls.put(names.elementAt(i), new UrlLink(names.elementAt(i) + SEP
242               + urlstrings.elementAt(i)));
243     }
244
245     // don't update until we're sure this set is ok
246     urls = newurls;
247
248   }
249
250   @Override
251   public String chooseDefaultUrl()
252   {
253     // unilaterally set the default id to the EMBL_EBI link
254     
255     if (!urls.containsKey(DEFAULT_LABEL))
256     {
257       urls.put(DEFAULT_LABEL, new UrlLink(DEFAULT_STRING));
258     }
259     defaultUrl = DEFAULT_LABEL;
260     return DEFAULT_LABEL;
261   }
262
263 }