0d5ef990ce6260f0b82f8c55360fb408ccc82251
[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     // upgrade old SRS link
164     if (urls.containsKey(SRS_LABEL))
165     {
166       urls.remove(SRS_LABEL);
167       UrlLink link = new UrlLink(UrlConstants.DEFAULT_STRING);
168       link.setLabel(UrlConstants.DEFAULT_LABEL);
169       urls.put(UrlConstants.DEFAULT_LABEL, link);
170     }
171   }
172
173   @Override
174   public List<String> getLinksForMenu()
175   {
176     List<String> links = new ArrayList<String>();
177     Iterator<Map.Entry<String, UrlLink>> it = selectedUrls.entrySet()
178             .iterator();
179     while (it.hasNext())
180     {
181       Map.Entry<String, UrlLink> pair = it.next();
182       links.add(pair.getValue().toString());
183     }
184     return links;
185   }
186
187   @Override
188   public List<UrlLinkDisplay> getLinksForTable()
189   {
190     ArrayList<UrlLinkDisplay> displayLinks = new ArrayList<UrlLinkDisplay>();
191     displayLinks = getLinksForTable(selectedUrls, true);
192     displayLinks.addAll(getLinksForTable(nonselectedUrls, false));
193     return displayLinks;
194   }
195
196   private ArrayList<UrlLinkDisplay> getLinksForTable(
197           HashMap<String, UrlLink> urlList, boolean selected)
198   {
199     return super.getLinksForTable(urlList, null, selected);
200   }
201
202   @Override
203   public boolean setPrimaryUrl(String id)
204   {
205     if (selectedUrls.containsKey(id))
206     {
207       primaryUrl = id;
208     }
209     else if (nonselectedUrls.containsKey(id))
210     {
211       primaryUrl = id;
212     }
213     else
214     {
215       primaryUrl = null;
216     }
217
218     return (primaryUrl != null);
219   }
220
221   @Override
222   public String writeUrlsAsString(boolean selected)
223   {
224     StringBuffer links = new StringBuffer();
225     HashMap<String, UrlLink> urls;
226     if (selected)
227     {
228       urls = selectedUrls;
229     }
230     else
231     {
232       urls = nonselectedUrls;
233     }
234     if (urls.size() > 0)
235     {
236       for (Entry<String, UrlLink> entry : urls.entrySet())
237       {
238         links.append(entry.getValue().toString());
239         links.append(SEP);
240       }
241
242       // remove last SEP
243       links.setLength(links.length() - 1);
244     }
245     else
246     {
247       urls.clear();
248     }
249     return links.toString();
250   }
251
252   @Override
253   public String getPrimaryUrl(String seqid)
254   {
255     String result = super.getPrimaryUrl(seqid, selectedUrls);
256     if (result == null)
257     {
258       result = super.getPrimaryUrl(seqid, nonselectedUrls);
259     }
260     return result;
261   }
262
263   @Override
264   public String getPrimaryUrlId()
265   {
266     return primaryUrl;
267   }
268
269   @Override
270   public String getPrimaryTarget(String seqid)
271   {
272     return selectedUrls.get(primaryUrl).getTarget();
273   }
274
275   @Override
276   public void setUrlData(List<UrlLinkDisplay> links)
277   {
278     HashMap<String, UrlLink> unselurls = new HashMap<String, UrlLink>();
279     HashMap<String, UrlLink> selurls = new HashMap<String, UrlLink>();
280
281     Iterator<UrlLinkDisplay> it = links.iterator();
282     while (it.hasNext())
283     {
284       UrlLinkDisplay link = it.next();
285
286       // MIRIAM ids will be handled by a different UrlProvider class
287       if (!isMiriamId(link.getId()))
288       {
289         // don't allow duplicate key names as entries will be overwritten
290         if (unselurls.containsKey(link.getId())
291                 || selurls.containsKey(link.getId()))
292         {
293           throw new IllegalArgumentException(MessageManager.formatMessage(
294                   "exception.url_cannot_have_duplicate_id", link.getId()));
295         }
296         if (link.getIsSelected())
297         {
298           selurls.put(link.getId(), new UrlLink(link.getDescription(),
299                   link.getUrl(), link.getDescription()));
300         }
301         else
302         {
303           unselurls.put(link.getId(), new UrlLink(link.getDescription(),
304                   link.getUrl(), link.getDescription()));
305         }
306         // sort out primary and selected ids
307         if (link.getIsPrimary())
308         {
309           setPrimaryUrl(link.getId());
310         }
311       }
312
313     }
314     nonselectedUrls = unselurls;
315     selectedUrls = selurls;
316   }
317
318   @Override
319   public String choosePrimaryUrl()
320   {
321     // unilaterally set the primary id to the EMBL_EBI link
322     if ((!nonselectedUrls.containsKey(UrlConstants.DEFAULT_LABEL))
323             && (!selectedUrls.containsKey(UrlConstants.DEFAULT_LABEL)))
324     {
325       UrlLink link = new UrlLink(UrlConstants.DEFAULT_STRING);
326       link.setLabel(UrlConstants.DEFAULT_LABEL);
327       selectedUrls.put(UrlConstants.DEFAULT_LABEL, link);
328     }
329     primaryUrl = UrlConstants.DEFAULT_LABEL;
330     return UrlConstants.DEFAULT_LABEL;
331   }
332
333   @Override
334   public boolean contains(String id)
335   {
336     return (selectedUrls.containsKey(id)
337             || nonselectedUrls.containsKey(id));
338   }
339
340 }