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