JAL-2756 update for new EBI https link
[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.UrlConstants;
31 import jalview.util.UrlLink;
32
33 import java.util.ArrayList;
34 import java.util.HashMap;
35 import java.util.Iterator;
36 import java.util.List;
37 import java.util.Map;
38 import java.util.Map.Entry;
39 import java.util.StringTokenizer;
40
41 /**
42  * 
43  * Implements the UrlProviderI interface for a UrlProvider object which serves
44  * custom URLs defined by the user
45  * 
46  * @author $author$
47  * @version $Revision$
48  */
49 public class CustomUrlProvider extends UrlProviderImpl
50 {
51   // Default sequence URL link label for SRS
52   private static final String SRS_LABEL = "SRS";
53
54   // map of string ids to urlLinks (selected)
55   private HashMap<String, UrlLink> selectedUrls;
56
57   // map of string ids to urlLinks (not selected)
58   private HashMap<String, UrlLink> nonselectedUrls;
59
60   /**
61    * Construct UrlProvider for custom (user-entered) URLs
62    * 
63    * @param inMenuUrlList
64    *          list of URLs set to be displayed in menu, in form stored in Cache.
65    *          i.e. SEP delimited string
66    * @param storedUrlList
67    *          list of custom URLs entered by user but not currently displayed in
68    *          menu, in form stored in Cache
69    */
70   public CustomUrlProvider(String inMenuUrlList, String storedUrlList)
71   {
72     try
73     {
74       selectedUrls = parseUrlStrings(inMenuUrlList);
75       nonselectedUrls = parseUrlStrings(storedUrlList);
76     } catch (Exception ex)
77     {
78       System.out
79               .println(ex.getMessage() + "\nError parsing sequence links");
80     }
81   }
82
83   /**
84    * Construct UrlProvider for custom (user-entered) URLs
85    * 
86    * @param urlList
87    *          list of URLs to be displayed in menu, as (label,url) pairs
88    * @param storedUrlList
89    *          list of custom URLs entered by user but not currently displayed in
90    *          menu, as (label,url) pairs
91    */
92   public CustomUrlProvider(Map<String, String> inMenuUrlList,
93           Map<String, String> storedUrlList)
94   {
95     try
96     {
97       selectedUrls = parseUrlList(inMenuUrlList);
98       nonselectedUrls = parseUrlList(storedUrlList);
99     } catch (Exception ex)
100     {
101       System.out
102               .println(ex.getMessage() + "\nError parsing sequence links");
103     }
104   }
105
106   private HashMap<String, UrlLink> parseUrlStrings(String urlStrings)
107   {
108     // cachedUrlList is in form <label>|<url>|<label>|<url>...
109     // parse cachedUrlList into labels (used as id) and url links
110     HashMap<String, UrlLink> urls = new HashMap<String, UrlLink>();
111
112     StringTokenizer st = new StringTokenizer(urlStrings, SEP);
113     while (st.hasMoreElements())
114     {
115       String name = st.nextToken();
116
117       if (!isMiriamId(name))
118       {
119         // this one of our custom urls
120         String url = st.nextToken();
121         // check for '|' within a regex
122         int rxstart = url.indexOf(DELIM + DB_ACCESSION + DELIM);
123         if (rxstart == -1)
124         {
125           rxstart = url.indexOf(DELIM + SEQUENCE_ID + DELIM);
126         }
127         while (rxstart == -1 && url.indexOf("/=" + DELIM) == -1
128                 && st.hasMoreTokens())
129         {
130           url = url + SEP + st.nextToken();
131         }
132         urls.put(name, new UrlLink(name, url, name));
133       }
134     }
135     upgradeOldLinks(urls);
136     return urls;
137   }
138
139   private HashMap<String, UrlLink> parseUrlList(Map<String, String> urlList)
140   {
141     HashMap<String, UrlLink> urls = new HashMap<String, UrlLink>();
142     if (urlList == null)
143     {
144       return urls;
145     }
146
147     Iterator<Map.Entry<String, String>> it = urlList.entrySet().iterator();
148     while (it.hasNext())
149     {
150       Map.Entry<String, String> pair = it.next();
151       urls.put(pair.getKey(),
152               new UrlLink(pair.getKey(), pair.getValue(), pair.getKey()));
153     }
154     upgradeOldLinks(urls);
155     return urls;
156   }
157
158   /*
159    * Upgrade any legacy links which may have been left lying around
160    */
161   private void upgradeOldLinks(HashMap<String, UrlLink> urls)
162   {
163     boolean upgrade = false;
164     // upgrade old SRS link
165     if (urls.containsKey(SRS_LABEL))
166     {
167       urls.remove(SRS_LABEL);
168       upgrade = true;
169     }
170     // upgrade old EBI link - easier just to remove and re-add than faffing
171     // around checking exact url
172     if (urls.containsKey(UrlConstants.DEFAULT_LABEL))
173     {
174       // note because this is called separately for selected and nonselected
175       // urls, the default url will not always be present
176       urls.remove(UrlConstants.DEFAULT_LABEL);
177       upgrade = true;
178     }
179     if (upgrade)
180     {
181       UrlLink link = new UrlLink(UrlConstants.DEFAULT_STRING);
182       link.setLabel(UrlConstants.DEFAULT_LABEL);
183       urls.put(UrlConstants.DEFAULT_LABEL, link);
184     }
185   }
186
187   @Override
188   public List<String> getLinksForMenu()
189   {
190     List<String> links = new ArrayList<String>();
191     Iterator<Map.Entry<String, UrlLink>> it = selectedUrls.entrySet()
192             .iterator();
193     while (it.hasNext())
194     {
195       Map.Entry<String, UrlLink> pair = it.next();
196       links.add(pair.getValue().toString());
197     }
198     return links;
199   }
200
201   @Override
202   public List<UrlLinkDisplay> getLinksForTable()
203   {
204     ArrayList<UrlLinkDisplay> displayLinks = new ArrayList<UrlLinkDisplay>();
205     displayLinks = getLinksForTable(selectedUrls, true);
206     displayLinks.addAll(getLinksForTable(nonselectedUrls, false));
207     return displayLinks;
208   }
209
210   private ArrayList<UrlLinkDisplay> getLinksForTable(
211           HashMap<String, UrlLink> urlList, boolean selected)
212   {
213     return super.getLinksForTable(urlList, null, selected);
214   }
215
216   @Override
217   public boolean setPrimaryUrl(String id)
218   {
219     if (selectedUrls.containsKey(id))
220     {
221       primaryUrl = id;
222     }
223     else if (nonselectedUrls.containsKey(id))
224     {
225       primaryUrl = id;
226     }
227     else
228     {
229       primaryUrl = null;
230     }
231
232     return (primaryUrl != null);
233   }
234
235   @Override
236   public String writeUrlsAsString(boolean selected)
237   {
238     StringBuffer links = new StringBuffer();
239     HashMap<String, UrlLink> urls;
240     if (selected)
241     {
242       urls = selectedUrls;
243     }
244     else
245     {
246       urls = nonselectedUrls;
247     }
248     if (urls.size() > 0)
249     {
250       for (Entry<String, UrlLink> entry : urls.entrySet())
251       {
252         links.append(entry.getValue().toString());
253         links.append(SEP);
254       }
255
256       // remove last SEP
257       links.setLength(links.length() - 1);
258     }
259     else
260     {
261       urls.clear();
262     }
263     return links.toString();
264   }
265
266   @Override
267   public String getPrimaryUrl(String seqid)
268   {
269     String result = super.getPrimaryUrl(seqid, selectedUrls);
270     if (result == null)
271     {
272       result = super.getPrimaryUrl(seqid, nonselectedUrls);
273     }
274     return result;
275   }
276
277   @Override
278   public String getPrimaryUrlId()
279   {
280     return primaryUrl;
281   }
282
283   @Override
284   public String getPrimaryTarget(String seqid)
285   {
286     return selectedUrls.get(primaryUrl).getTarget();
287   }
288
289   @Override
290   public void setUrlData(List<UrlLinkDisplay> links)
291   {
292     HashMap<String, UrlLink> unselurls = new HashMap<String, UrlLink>();
293     HashMap<String, UrlLink> selurls = new HashMap<String, UrlLink>();
294
295     Iterator<UrlLinkDisplay> it = links.iterator();
296     while (it.hasNext())
297     {
298       UrlLinkDisplay link = it.next();
299
300       // MIRIAM ids will be handled by a different UrlProvider class
301       if (!isMiriamId(link.getId()))
302       {
303         // don't allow duplicate key names as entries will be overwritten
304         if (unselurls.containsKey(link.getId())
305                 || selurls.containsKey(link.getId()))
306         {
307           throw new IllegalArgumentException(MessageManager.formatMessage(
308                   "exception.url_cannot_have_duplicate_id", link.getId()));
309         }
310         if (link.getIsSelected())
311         {
312           selurls.put(link.getId(), new UrlLink(link.getDescription(),
313                   link.getUrl(), link.getDescription()));
314         }
315         else
316         {
317           unselurls.put(link.getId(), new UrlLink(link.getDescription(),
318                   link.getUrl(), link.getDescription()));
319         }
320         // sort out primary and selected ids
321         if (link.getIsPrimary())
322         {
323           setPrimaryUrl(link.getId());
324         }
325       }
326
327     }
328     nonselectedUrls = unselurls;
329     selectedUrls = selurls;
330   }
331
332   @Override
333   public String choosePrimaryUrl()
334   {
335     // unilaterally set the primary id to the EMBL_EBI link
336     if ((!nonselectedUrls.containsKey(UrlConstants.DEFAULT_LABEL))
337             && (!selectedUrls.containsKey(UrlConstants.DEFAULT_LABEL)))
338     {
339       UrlLink link = new UrlLink(UrlConstants.DEFAULT_STRING);
340       link.setLabel(UrlConstants.DEFAULT_LABEL);
341       selectedUrls.put(UrlConstants.DEFAULT_LABEL, link);
342     }
343     primaryUrl = UrlConstants.DEFAULT_LABEL;
344     return UrlConstants.DEFAULT_LABEL;
345   }
346
347   @Override
348   public boolean contains(String id)
349   {
350     return (selectedUrls.containsKey(id)
351             || nonselectedUrls.containsKey(id));
352   }
353
354 }