JAL-1705 regular expression updates, tests, other refactoring
[jalview.git] / src / jalview / ext / ensembl / EnsemblXref.java
1 package jalview.ext.ensembl;
2
3 import jalview.datamodel.AlignmentI;
4 import jalview.datamodel.DBRefEntry;
5 import jalview.util.DBRefUtils;
6
7 import java.io.BufferedReader;
8 import java.io.IOException;
9 import java.net.MalformedURLException;
10 import java.net.URL;
11 import java.util.ArrayList;
12 import java.util.Iterator;
13 import java.util.List;
14
15 import org.json.simple.JSONArray;
16 import org.json.simple.JSONObject;
17 import org.json.simple.parser.JSONParser;
18 import org.json.simple.parser.ParseException;
19
20 /**
21  * A class to fetch cross-references from Ensembl by calling the /xrefs REST
22  * service
23  * 
24  * @author gmcarstairs
25  * @see http://rest.ensembl.org/documentation/info/xref_id
26  */
27 class EnsemblXref extends EnsemblRestClient
28 {
29
30   @Override
31   public String getDbName()
32   {
33     return "ENSEMBL (xref)";
34   }
35
36   @Override
37   public AlignmentI getSequenceRecords(String queries) throws Exception
38   {
39     return null;
40   }
41
42   @Override
43   protected URL getUrl(List<String> ids) throws MalformedURLException
44   {
45     return getUrl(ids.get(0));
46   }
47
48   @Override
49   protected boolean useGetRequest()
50   {
51     return true;
52   }
53
54   @Override
55   protected String getRequestMimeType(boolean multipleIds)
56   {
57     return "application/json";
58   }
59
60   @Override
61   protected String getResponseMimeType()
62   {
63     return "application/json";
64   }
65
66   /**
67    * Calls the Ensembl xrefs REST endpoint and retrieves any cross-references
68    * ("primary_id") for the given identifier (Ensembl accession id) and database
69    * names. The "dbname" returned by Ensembl is canonicalised to Jalview's
70    * standard version, and a DBRefEntry constructed. If no databases are
71    * specified, all available cross-references are retrieved.
72    * 
73    * @param identifier
74    * @param databases
75    * @return
76    */
77   public List<DBRefEntry> getCrossReferences(String identifier,
78           List<String> databases)
79   {
80     List<DBRefEntry> result = new ArrayList<DBRefEntry>();
81     List<String> ids = new ArrayList<String>();
82     ids.add(identifier);
83
84     BufferedReader br = null;
85     try
86     {
87       URL url = getUrl(identifier);
88         if (url != null)
89         {
90           br = getHttpResponse(url, ids);
91         }
92       return (parseResponse(br, databases));
93     } catch (IOException e)
94     {
95       // ignore
96     } finally
97     {
98       if (br != null)
99       {
100         try
101         {
102           br.close();
103         } catch (IOException e)
104         {
105           // ignore
106         }
107       }
108     }
109
110     return result;
111   }
112
113   /**
114    * Parses "primary_id" and "dbname" values from the JSON response and
115    * constructs a DBRefEntry if the dbname is in the list supplied. Returns a
116    * list of DBRefEntry created.
117    * 
118    * @param br
119    * @param databases
120    * @return
121    * @throws IOException
122    */
123   protected List<DBRefEntry> parseResponse(BufferedReader br,
124           List<String> databases)
125           throws IOException
126   {
127     JSONParser jp = new JSONParser();
128     List<DBRefEntry> result = new ArrayList<DBRefEntry>();
129     try
130     {
131       JSONArray responses = (JSONArray) jp.parse(br);
132       Iterator rvals = responses.iterator();
133       while (rvals.hasNext())
134       {
135         JSONObject val = (JSONObject) rvals.next();
136         String dbName = val.get("dbname").toString();
137         if (databases != null && !databases.isEmpty()
138                 && !databases.contains(dbName))
139         {
140           continue;
141         }
142         String id = val.get("primary_id").toString();
143         if (dbName != null && id != null)
144         {
145           dbName = DBRefUtils.getCanonicalName(dbName);
146           DBRefEntry dbref = new DBRefEntry(dbName, "0", id);
147           result.add(dbref);
148         }
149       }
150     } catch (ParseException e)
151     {
152       // ignore
153     }
154     return result;
155   }
156
157   /**
158    * Returns the URL for the REST endpoint to fetch all cross-references for an
159    * identifier. Note this may return protein cross-references for nucleotide.
160    * Filter the returned list as required.
161    * 
162    * @param identifier
163    * @return
164    */
165   protected URL getUrl(String identifier)
166   {
167     String url = ENSEMBL_REST + "/xrefs/id/" + identifier
168             + "?content-type=application/json&all_levels=1";
169     try
170     {
171       return new URL(url);
172     } catch (MalformedURLException e)
173     {
174       return null;
175     }
176   }
177
178 }