JAL-2316 Adjusted unit tests. Tidied UrlLinkProviderI interface.
[jalview.git] / src / jalview / urls / IdentifiersUrlProvider.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
28 import java.io.BufferedInputStream;
29 import java.io.File;
30 import java.io.FileNotFoundException;
31 import java.io.FileOutputStream;
32 import java.io.FileReader;
33 import java.io.IOException;
34 import java.io.InputStream;
35 import java.net.URL;
36 import java.util.ArrayList;
37 import java.util.HashMap;
38 import java.util.Iterator;
39 import java.util.List;
40 import java.util.Map.Entry;
41 import java.util.Vector;
42
43 import org.json.simple.JSONArray;
44 import org.json.simple.JSONObject;
45 import org.json.simple.parser.JSONParser;
46 import org.json.simple.parser.ParseException;
47
48 /**
49  * 
50  * Implements the UrlProviderI interface for a UrlProvider object which serves
51  * URLs from identifiers.org
52  * 
53  * @author $author$
54  * @version $Revision$
55  */
56 public class IdentifiersUrlProvider extends UrlProviderImpl
57 {
58
59   // map of string ids to urls
60   private HashMap<String, HashMap<String, String>> urls;
61
62   // list of selected urls
63   private ArrayList<String> selectedUrls;
64
65   /*
66    * Location of file for identifiers.org download
67    */
68   public static final String ID_ORG_FILE = System.getProperty("user.home")
69           + File.separatorChar + ".jalview_identifiers";
70
71   public IdentifiersUrlProvider(String cachedUrlList, String idFileName)
72   {
73     try
74     {
75       // File idFile = getIdentifiers();
76       urls = readIdentifiers(new FileReader(idFileName));
77       selectedUrls = new ArrayList<String>();
78       checkSelectionMatchesUrls(cachedUrlList);
79
80     } catch (IOException e)
81     {
82       System.out.println("Exception reading URLs from identifiers.org");
83       System.out.println(e.getMessage());
84     }
85   }
86
87   private File getIdentifiers() throws IOException
88   {
89     String identifiersorgUrl = "http://identifiers.org/rest/collections/";
90     String outfile = "identifiers.json";
91     int BUFFER_SIZE = 4096;
92     
93     URL url = new URL(identifiersorgUrl);
94     InputStream is = new BufferedInputStream(url.openStream());
95     FileOutputStream os = new FileOutputStream(outfile);
96     byte[] buffer = new byte[BUFFER_SIZE];
97     int bytesRead = -1;
98     while ((bytesRead = is.read(buffer)) != -1)
99     {
100       os.write(buffer, 0, bytesRead);
101     }
102     os.close();
103     is.close();
104     
105     return new File(outfile);
106   }
107
108   private HashMap<String, HashMap<String, String>> readIdentifiers(
109           FileReader reader)
110   {
111     JSONParser parser = new JSONParser();
112     HashMap<String, HashMap<String, String>> idData = new HashMap<String, HashMap<String, String>>();
113
114     try
115     {
116       JSONArray jsonarray = (JSONArray) parser.parse(reader);
117
118       // loop over each entry in JSON array and build HashMap entry
119       for (int i = 0; i < jsonarray.size(); i++)
120       {
121         JSONObject item = (JSONObject) jsonarray.get(i);
122
123         HashMap<String, String> idEntry = new HashMap<String, String>();
124         idEntry.put("name", (String) item.get("name"));
125         idEntry.put("url", (String) item.get("url"));
126         idData.put((String) item.get("id"), idEntry);
127       }
128     } catch (FileNotFoundException e)
129     {
130       e.printStackTrace();
131     } catch (IOException e)
132     {
133       e.printStackTrace();
134     } catch (ParseException e)
135     {
136       e.printStackTrace();
137     }
138     return idData;
139   }
140
141   private void checkSelectionMatchesUrls(String cachedUrlList)
142   {
143
144     String[] prevSelected = cachedUrlList.split("\\" + SEP);
145     for (String id : prevSelected)
146     {
147       if (urls.containsKey(id))
148       {
149         selectedUrls.add(id);
150       }
151     }
152
153     // reset defaultUrl in case it is no longer selected
154     setDefaultUrl(defaultUrl);
155   }
156
157   private void checkSelectionMatchesUrls(Vector<String> idList)
158   {
159     String[] prevSelected = new String[idList.size()];
160     idList.toArray(prevSelected);
161     for (String id : prevSelected)
162     {
163       if (urls.containsKey(id))
164       {
165         selectedUrls.add(id);
166       }
167     }
168
169     // reset defaultUrl in case it is no longer selected
170     setDefaultUrl(defaultUrl);
171   }
172
173   @Override
174   public boolean setDefaultUrl(String id)
175   {
176     if (selectedUrls.contains(id))
177     {
178       defaultUrl = id;
179     }
180     else
181     {
182       defaultUrl = null;
183     }
184     return selectedUrls.contains(id);
185   }
186
187   @Override
188   public String writeUrlsAsString()
189   {
190     if (!selectedUrls.isEmpty())
191     {
192       StringBuffer links = new StringBuffer();
193       for (String k : selectedUrls)
194       {
195         links.append(k);
196         links.append(SEP);
197       }
198       // remove last SEP
199       links.setLength(links.length() - 1);
200       return links.toString();
201     }
202     return "";
203   }
204
205   @Override
206   public Vector<String> getLinksForMenu()
207   {
208     Vector<String> links = new Vector<String>();
209     for (String key : selectedUrls)
210     {
211       links.add(urls.get(key).get("name") + SEP + urls.get(key).get("url")
212               + "/" + DELIM
213               + DB_ACCESSION + DELIM);
214     }
215     return links;
216   }
217
218   @Override
219   public List<UrlLinkDisplay> getLinksForTable()
220   {
221     ArrayList<UrlLinkDisplay> displayLinks = new ArrayList<UrlLinkDisplay>();
222     for (Entry<String, HashMap<String, String>> entry : urls.entrySet())
223     {
224       String key = entry.getKey();
225       boolean isDefault = (key == defaultUrl);
226       boolean isSelected = (selectedUrls.contains(key));
227       displayLinks.add(new UrlLinkDisplay(key,
228               entry.getValue().get("name"),
229               entry.getValue().get("url")
230               + "/" + DELIM + DB_ACCESSION + DELIM, isSelected, isDefault));
231     }
232     return displayLinks;
233   }
234
235   @Override
236   public void setUrlData(List<UrlLinkDisplay> links)
237   {
238     selectedUrls = new ArrayList<String>();
239
240     Iterator<UrlLinkDisplay> it = links.iterator();
241     while (it.hasNext())
242     {
243       UrlLinkDisplay link = it.next();
244
245       // Handle links with MIRIAM ids only
246       if (isMiriamId(link.getId())) // TODO separate use of name and id
247       {
248         // select/deselect links accordingly and set default url
249
250         if (link.getIsSelected())
251         {
252           if (urls.containsKey(link.getId()))
253           {
254             selectedUrls.add(link.getId());
255           }
256           if (link.getIsDefault())
257           {
258             setDefaultUrl(link.getId());
259           }
260
261         }
262       }
263
264     }
265   }
266
267   @Override
268   public String getDefaultUrl(String seqid)
269   {
270     if (seqid.length() < MIN_SUBST_LENGTH)
271     {
272       return null;
273     }
274     else if (defaultUrl == null)
275     {
276       return null;
277     }
278     else
279     {
280       return urls.get(defaultUrl).get("url") + "/" + seqid;
281     }
282   }
283
284   @Override
285   public String getDefaultTarget(String seqid)
286   {
287     // TODO Auto-generated method stub
288     return null;
289   }
290
291   @Override
292   public String chooseDefaultUrl()
293   {
294     // TODO Auto-generated method stub
295     return null;
296   }
297
298 }