ec594b653691458559721f0916fc92e18b893b86
[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, isDefault));
171     }
172     return displayLinks;
173   }
174
175   @Override
176   public boolean setDefaultUrl(String id)
177   {
178     if (urls.containsKey(id))
179     {
180       defaultUrl = id;
181     }
182     else
183     {
184       defaultUrl = null;
185     }
186     return urls.containsKey(id);
187   }
188
189   @Override
190   public String writeUrlsAsString()
191   {
192     StringBuffer links = new StringBuffer();
193     if (urls.size() > 0)
194     {
195       for (UrlLink link : urls.values())
196       {
197         links.append(link.toString());
198         links.append(SEP);
199       }
200
201       // remove last SEP
202       links.setLength(links.length() - 1);
203     }
204     else
205     {
206       urls.clear();
207     }
208     return links.toString();
209   }
210
211   @Override
212   public String getDefaultUrl(String seqid)
213   {
214     if (defaultUrl == null)
215     {
216       return null;
217     }
218
219     String url = null;
220     UrlLink urlLink = urls.get(defaultUrl);
221     String[] defaultUrls = urlLink.makeUrls(seqid, true);
222     if (defaultUrls == null || defaultUrls[0] == null
223             || defaultUrls[0].length() < MIN_SUBST_LENGTH)
224     {
225       url = null;
226     }
227     else
228     {
229       // just take first URL made from regex
230       url = defaultUrls[1];
231     }
232     return url;
233   }
234
235   @Override
236   public String getDefaultTarget(String seqid)
237   {
238     return urls.get(defaultUrl).getTarget();
239   }
240
241   @Override
242   public void setUrlData(List<UrlLinkDisplay> links)
243   {
244     HashMap<String, UrlLink> newurls = new HashMap<String, UrlLink>();
245
246     Iterator<UrlLinkDisplay> it = links.iterator();
247     while (it.hasNext())
248     {
249       UrlLinkDisplay link = it.next();
250
251       // MIRIAM ids will be handled by a different UrlProvider class
252       if (!isMiriamId(link.getId()))
253       {
254
255         // don't allow duplicate key names as entries will be overwritten
256         if (newurls.containsKey(link.getId()))
257         {
258           throw new IllegalArgumentException(MessageManager.formatMessage(
259                   "exception.url_cannot_have_duplicate_id", link.getId()));
260         }
261         if (link.getIsSelected())
262         {
263           newurls.put(link.getId(),
264                   new UrlLink(link.getId() + SEP + link.getUrl()));
265
266           // sort out default and selected ids
267           if (link.getIsDefault())
268           {
269             setDefaultUrl(link.getId());
270           }
271         }
272           // TODO KM make it possible to set and save selected custom urls
273
274       }
275
276     }
277     urls = newurls;
278   }
279
280   @Override
281   public String chooseDefaultUrl()
282   {
283     // unilaterally set the default id to the EMBL_EBI link
284     
285     if (!urls.containsKey(UrlConstants.DEFAULT_LABEL))
286     {
287       urls.put(UrlConstants.DEFAULT_LABEL, new UrlLink(UrlConstants.DEFAULT_STRING));
288     }
289     defaultUrl = UrlConstants.DEFAULT_LABEL;
290     return UrlConstants.DEFAULT_LABEL;
291   }
292
293 }