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