JAL-2316 Adjusted unit tests. Tidied UrlLinkProviderI interface.
[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 import java.util.Vector;
41
42 /**
43  * 
44  * Implements the UrlProviderI interface for a UrlProvider object which serves
45  * custom URLs defined by the user
46  * 
47  * @author $author$
48  * @version $Revision$
49  */
50 public class CustomUrlProvider extends UrlProviderImpl
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
77         if (!isMiriamId(name))
78         {
79           // this one of our custom urls
80           String url = st.nextToken();
81           // check for '|' within a regex
82           int rxstart = url.indexOf(DELIM + DB_ACCESSION + DELIM);
83           if (rxstart == -1)
84           {
85             rxstart = url.indexOf(DELIM + SEQUENCE_ID + DELIM);
86           }
87           while (rxstart == -1 && url.indexOf("/=" + DELIM) == -1
88                   && st.hasMoreTokens())
89           {
90             url = url + SEP + st.nextToken();
91           }
92           urls.put(name, new UrlLink(name + SEP + url));
93         }
94       }
95     } catch (Exception ex)
96     {
97       System.out.println(ex + "\nError parsing sequence links");
98     }
99     upgradeOldLinks();
100
101   }
102
103   /**
104    * Construct UrlProvider for custom (user-entered) URLs
105    * 
106    * @param urlList
107    *          list of URLs as (label,url) pairs
108    */
109   public CustomUrlProvider(Map<String, String> urlList)
110   {
111     try
112     {
113       urls = new HashMap<String, UrlLink>();
114       Iterator<Map.Entry<String, String>> it = urlList.entrySet()
115               .iterator();
116       while (it.hasNext())
117       {
118         Map.Entry<String, String> pair = it.next();
119         urls.put(pair.getKey(),
120                 new UrlLink(pair.getKey() + SEP + pair.getValue()));
121       }
122     } catch (Exception ex)
123     {
124       System.out.println(ex + "\nError parsing sequence links");
125     }
126     upgradeOldLinks();
127   }
128
129   /*
130    * Upgrade any legacy links which may have been left lying around
131    */
132   private void upgradeOldLinks()
133   {
134     // upgrade old SRS link
135     if (urls.containsKey(SRS_LABEL))
136     {
137       urls.remove(SRS_LABEL);
138       urls.put(UrlConstants.DEFAULT_LABEL, new UrlLink(UrlConstants.DEFAULT_STRING));
139     }
140   }
141
142   @Override
143   public Vector<String> getLinksForMenu()
144   {
145     Vector<String> links = new Vector<String>();
146     Iterator<Map.Entry<String, UrlLink>> it = urls.entrySet().iterator();
147     while (it.hasNext())
148     {
149       Map.Entry<String, UrlLink> pair = it.next();
150       links.add(pair.getValue().toString());
151     }
152     return links;
153   }
154
155   @Override
156   public List<UrlLinkDisplay> getLinksForTable()
157   {
158     ArrayList<UrlLinkDisplay> displayLinks = new ArrayList<UrlLinkDisplay>();
159     for (Entry<String, UrlLink> entry : urls.entrySet())
160     {
161       String key = entry.getKey();
162       boolean isDefault = (key.equals(defaultUrl));
163       boolean isSelected = true; // custom urls always selected
164       String displayLink = entry.getValue().toString().split("\\|")[1]; // TODO
165                                                                         // sort
166                                                                         // this
167                                                                         // out
168                                                                         // properly!
169       displayLinks.add(new UrlLinkDisplay(key, key, displayLink,
170               isSelected,
171               isDefault));
172     }
173     return displayLinks;
174   }
175
176   @Override
177   public boolean setDefaultUrl(String id)
178   {
179     if (urls.containsKey(id))
180     {
181       defaultUrl = id;
182     }
183     else
184     {
185       defaultUrl = null;
186     }
187     return urls.containsKey(id);
188   }
189
190   @Override
191   public String writeUrlsAsString()
192   {
193     StringBuffer links = new StringBuffer();
194     if (urls.size() > 0)
195     {
196       for (UrlLink link : urls.values())
197       {
198         links.append(link.toString());
199         links.append(SEP);
200       }
201
202       // remove last SEP
203       links.setLength(links.length() - 1);
204     }
205     else
206     {
207       urls.clear();
208     }
209     return links.toString();
210   }
211
212   @Override
213   public String getDefaultUrl(String seqid)
214   {
215     if (defaultUrl == null)
216     {
217       return null;
218     }
219
220     String url = null;
221     UrlLink urlLink = urls.get(defaultUrl);
222     String[] defaultUrls = urlLink.makeUrls(seqid, true);
223     if (defaultUrls == null || defaultUrls[0] == null
224             || defaultUrls[0].length() < MIN_SUBST_LENGTH)
225     {
226       url = null;
227     }
228     else
229     {
230       // just take first URL made from regex
231       url = defaultUrls[1];
232     }
233     return url;
234   }
235
236   @Override
237   public String getDefaultTarget(String seqid)
238   {
239     return urls.get(defaultUrl).getTarget();
240   }
241
242   @Override
243   public void setUrlData(List<UrlLinkDisplay> links)
244   {
245     HashMap<String, UrlLink> newurls = new HashMap<String, UrlLink>();
246
247     Iterator<UrlLinkDisplay> it = links.iterator();
248     while (it.hasNext())
249     {
250       UrlLinkDisplay link = it.next();
251
252       // MIRIAM ids will be handled by a different UrlProvider class
253       if (!isMiriamId(link.getId()))
254       {
255
256         // don't allow duplicate key names as entries will be overwritten
257         if (newurls.containsKey(link.getId()))
258         {
259           throw new IllegalArgumentException(MessageManager.formatMessage(
260                   "exception.url_cannot_have_duplicate_id", link.getId()));
261         }
262         if (link.getIsSelected())
263         {
264           newurls.put(link.getId(),
265                   new UrlLink(link.getId() + SEP + link.getUrl()));
266
267           // sort out default and selected ids
268           if (link.getIsDefault())
269           {
270             setDefaultUrl(link.getId());
271           }
272         }
273           // TODO KM make it possible to set and save selected custom urls
274
275       }
276
277     }
278     urls = newurls;
279   }
280
281   @Override
282   public String chooseDefaultUrl()
283   {
284     // unilaterally set the default id to the EMBL_EBI link
285     
286     if (!urls.containsKey(UrlConstants.DEFAULT_LABEL))
287     {
288       urls.put(UrlConstants.DEFAULT_LABEL, new UrlLink(UrlConstants.DEFAULT_STRING));
289     }
290     defaultUrl = UrlConstants.DEFAULT_LABEL;
291     return UrlConstants.DEFAULT_LABEL;
292   }
293
294 }