JAL-2316 Refactoring of functionality to provide urls to gui
[jalview.git] / src / jalview / util / 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.util;
23
24 import static jalview.util.UrlConstants.DB_ACCESSION;
25 import static jalview.util.UrlConstants.DELIM;
26 //import static jalview.util.UrlConstants.EMBLEBI_LABEL;
27 //import static jalview.util.UrlConstants.EMBLEBI_STRING;
28 import static jalview.util.UrlConstants.SEP;
29 import static jalview.util.UrlConstants.SEQUENCE_ID;
30 //import static jalview.util.UrlConstants.SRS_LABEL;
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         {
85           url = url + SEP + st.nextToken();
86         }
87         urls.put(name, new UrlLink(name + SEP + url));
88       }
89     } catch (Exception ex)
90     {
91       System.out.println(ex + "\nError parsing sequence links");
92     }
93     upgradeOldLinks();
94
95   }
96
97   /**
98    * Construct UrlProvider for custom (user-entered) URLs
99    * 
100    * @param urlList
101    *          list of URLs as (label,url) pairs
102    */
103   public CustomUrlProvider(Map<String, String> urlList)
104   {
105     try
106     {
107       urls = new HashMap<String, UrlLink>();
108       Iterator<Map.Entry<String, String>> it = urlList.entrySet()
109               .iterator();
110       while (it.hasNext())
111       {
112         Map.Entry<String, String> pair = it.next();
113         urls.put(pair.getKey(),
114                 new UrlLink(pair.getKey() + SEP + pair.getValue()));
115       }
116     } catch (Exception ex)
117     {
118       System.out.println(ex + "\nError parsing sequence links");
119     }
120     upgradeOldLinks();
121   }
122
123   private void upgradeOldLinks()
124   {
125     // upgrade old SRS link
126     if (urls.containsKey(SRS_LABEL))
127     {
128       urls.remove(SRS_LABEL);
129       urls.put(DEFAULT_LABEL, new UrlLink(DEFAULT_STRING));
130     }
131   }
132
133   @Override
134   public Vector<String> getLinksForDisplay()
135   {
136     Vector<String> links = new Vector<String>();
137     Iterator<Map.Entry<String, UrlLink>> it = urls.entrySet().iterator();
138     while (it.hasNext())
139     {
140       Map.Entry<String, UrlLink> pair = it.next();
141       links.add(pair.getValue().toString());
142     }
143     return links;
144   }
145
146   @Override
147   public boolean setDefaultUrl(String id)
148   {
149     if (urls.containsKey(id))
150     {
151       defaultUrl = id;
152     }
153     else
154     {
155       defaultUrl = null;
156     }
157     return urls.containsKey(id);
158   }
159
160   @Override
161   public String writeUrlsAsString()
162   {
163     StringBuffer links = new StringBuffer();
164     if (urls.size() > 0)
165     {
166       for (UrlLink link : urls.values())
167       {
168         links.append(link.toString());
169         links.append(SEP);
170       }
171
172       // remove last SEP
173       links.setLength(links.length() - 1);
174     }
175     else
176     {
177       urls.clear();
178     }
179     return links.toString();
180   }
181
182   @Override
183   public String getDefaultUrl(String seqid)
184   {
185     if (defaultUrl == null)
186     {
187       return null;
188     }
189
190     String url = null;
191     UrlLink urlLink = urls.get(defaultUrl);
192     String[] defaultUrls = urlLink.makeUrls(seqid, true);
193     if (defaultUrls == null || defaultUrls[0] == null
194             || defaultUrls[0].length() < MIN_SUBST_LENGTH)
195     {
196       url = null;
197     }
198     else
199     {
200       // just take first URL made from regex
201       url = defaultUrls[1];
202     }
203     return url;
204   }
205
206   @Override
207   public String getDefaultTarget(String seqid)
208   {
209     return urls.get(defaultUrl).getTarget();
210   }
211
212   @Override
213   public void setUrlLinks(Vector<String> names, Vector<String> urlstrings)
214   {
215     HashMap<String, UrlLink> newurls = new HashMap<String, UrlLink>();
216
217     // should check that lists are same length but this function is likely
218     // to change once the Preferences dialog is rebuilt
219
220     for (int i = 0; i < names.size(); ++i)
221     {
222       // don't allow MIRIAM ids as custom url names (as the links will overwrite
223       // each other)
224       // unlikely user would try to do this, but...
225       if (isMiriamId(names.elementAt(i)))
226       {
227         throw new IllegalArgumentException(MessageManager.formatMessage(
228                 "exception.url_cannot_have_miriam_id", names.elementAt(i)));
229       }
230       // don't allow duplicate key names as entries will be overwritten
231       if (newurls.containsKey(names.elementAt(i)))
232       {
233         throw new IllegalArgumentException(MessageManager.formatMessage(
234                 "exception.url_cannot_have_duplicate_id",
235                 names.elementAt(i)));
236       }
237       newurls.put(names.elementAt(i), new UrlLink(names.elementAt(i) + SEP
238               + urlstrings.elementAt(i)));
239     }
240
241     // don't update until we're sure this set is ok
242     urls = newurls;
243
244   }
245
246   @Override
247   public String chooseDefaultUrl()
248   {
249     // unilaterally set the default id to the EMBL_EBI link
250     
251     if (!urls.containsKey(DEFAULT_LABEL))
252     {
253       urls.put(DEFAULT_LABEL, new UrlLink(DEFAULT_STRING));
254     }
255     return DEFAULT_LABEL;
256   }
257
258 }