JAL-1563 Fixed Uniprot FTS result-set count error, added blank image placeholder...
[jalview.git] / src / jalview / fts / service / uniprot / UniProtFTSRestClient.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.fts.service.uniprot;
23
24 import jalview.fts.api.FTSData;
25 import jalview.fts.api.FTSDataColumnI;
26 import jalview.fts.api.FTSRestClientI;
27 import jalview.fts.core.FTSRestClient;
28 import jalview.fts.core.FTSRestRequest;
29 import jalview.fts.core.FTSRestResponse;
30
31 import java.util.ArrayList;
32 import java.util.Collection;
33 import java.util.List;
34 import java.util.Objects;
35
36 import javax.ws.rs.core.MediaType;
37
38 import com.sun.jersey.api.client.Client;
39 import com.sun.jersey.api.client.ClientResponse;
40 import com.sun.jersey.api.client.WebResource;
41 import com.sun.jersey.api.client.config.ClientConfig;
42 import com.sun.jersey.api.client.config.DefaultClientConfig;
43
44 public class UniProtFTSRestClient extends FTSRestClient
45 {
46   private static FTSRestClientI instance = null;
47
48   public static final String UNIPROT_SEARCH_ENDPOINT = "http://www.uniprot.org/uniprot/?";
49
50   @Override
51   public FTSRestResponse executeRequest(FTSRestRequest uniportRestRequest)
52   {
53     ClientConfig clientConfig = new DefaultClientConfig();
54     Client client = Client.create(clientConfig);
55
56     String wantedFields = getDataColumnsFieldsAsCommaDelimitedString(uniportRestRequest
57             .getWantedFields());
58     int responseSize = (uniportRestRequest.getResponseSize() == 0) ? getDefaultResponsePageSize()
59             : uniportRestRequest.getResponseSize();
60
61     int offSet = uniportRestRequest.getOffSet();
62
63     String query = uniportRestRequest.getFieldToSearchBy()
64             .equalsIgnoreCase("Search All") ? uniportRestRequest
65             .getSearchTerm()
66             : uniportRestRequest.getFieldToSearchBy() + ":"
67                     + uniportRestRequest.getSearchTerm();
68
69     // + (uniportRestRequest.isAllowUnpublishedEntries() ? ""
70     // : " AND status:REL");
71     // System.out.println(">>>>> Query : " + query);
72     // System.out.println(">>>>> Columns : " + wantedFields);
73     // System.out.println(">>>>> Response size: " + responseSize
74     // + " offset : "
75     // + offSet);
76     WebResource webResource = null;
77     webResource = client.resource(UNIPROT_SEARCH_ENDPOINT)
78             .queryParam("format", "tab")
79             .queryParam("columns", wantedFields)
80             .queryParam("limit", String.valueOf(responseSize))
81             .queryParam("offset", String.valueOf(offSet))
82             .queryParam("sort", "score")
83             .queryParam("query", query);
84     // Execute the REST request
85     ClientResponse clientResponse = webResource
86             .accept(MediaType.TEXT_PLAIN).get(ClientResponse.class);
87     String uniProtTabDelimittedResponseString = clientResponse
88             .getEntity(String.class);
89     // Make redundant objects eligible for garbage collection to conserve
90     // memory
91     clientResponse = null;
92     client = null;
93     // System.out.println(">>>>> response : "
94     // + uniProtTabDelimittedResponseString);
95     return parseUniprotResponse(uniProtTabDelimittedResponseString,
96             uniportRestRequest);
97
98   }
99
100   public FTSRestResponse parseUniprotResponse(
101           String uniProtTabDelimittedResponseString,
102           FTSRestRequest uniprotRestRequest)
103   {
104     FTSRestResponse searchResult = new FTSRestResponse();
105     List<FTSData> result = null;
106     if (uniProtTabDelimittedResponseString == null
107             || uniProtTabDelimittedResponseString.trim().isEmpty())
108     {
109       searchResult.setNumberOfItemsFound(0);
110       return searchResult;
111     }
112     String[] foundDataRow = uniProtTabDelimittedResponseString.split("\n");
113     if (foundDataRow != null && foundDataRow.length > 0)
114     {
115       result = new ArrayList<FTSData>();
116       String titleRow = getDataColumnsFieldsAsTabDelimitedString(uniprotRestRequest
117               .getWantedFields());
118       // System.out.println(">>>>Title row : " + titleRow);
119       for (String dataRow : foundDataRow)
120       {
121         if (dataRow.equalsIgnoreCase(titleRow))
122         {
123           // System.out.println(">>>>>>>>>> matched!!!");
124           continue;
125         }
126         // System.out.println(dataRow);
127         result.add(getFTSData(dataRow, uniprotRestRequest));
128       }
129       searchResult.setNumberOfItemsFound(result.size());
130       searchResult.setSearchSummary(result);
131     }
132     return searchResult;
133   }
134
135   /**
136    * Takes a collection of FTSDataColumnI and converts its 'code' values into a
137    * tab delimited string.
138    * 
139    * @param dataColumnFields
140    *          the collection of FTSDataColumnI to process
141    * @return the generated comma delimited string from the supplied
142    *         FTSDataColumnI collection
143    */
144   private String getDataColumnsFieldsAsTabDelimitedString(
145           Collection<FTSDataColumnI> dataColumnFields)
146   {
147     String result = "";
148     if (dataColumnFields != null && !dataColumnFields.isEmpty())
149     {
150       StringBuilder returnedFields = new StringBuilder();
151       for (FTSDataColumnI field : dataColumnFields)
152       {
153         if (field.getName().equalsIgnoreCase("Uniprot Id"))
154         {
155           returnedFields.append("\t").append("Entry");
156         }
157         else
158         {
159           returnedFields.append("\t").append(field.getName());
160         }
161       }
162       returnedFields.deleteCharAt(0);
163       result = returnedFields.toString();
164     }
165     return result;
166   }
167   public static FTSData getFTSData(String tabDelimittedDataStr,
168           FTSRestRequest request)
169   {
170     String primaryKey = null;
171
172     Object[] summaryRowData;
173
174     Collection<FTSDataColumnI> diplayFields = request.getWantedFields();
175     int colCounter = 0;
176     summaryRowData = new Object[diplayFields.size()];
177     String[] columns = tabDelimittedDataStr.split("\t");
178     for (FTSDataColumnI field : diplayFields)
179     {
180       try
181       {
182         String fieldData = columns[colCounter];
183         if (field.isPrimaryKeyColumn())
184         {
185           primaryKey = fieldData;
186           summaryRowData[colCounter++] = primaryKey;
187         }
188         else if (fieldData == null || fieldData.isEmpty())
189         {
190           summaryRowData[colCounter++] = null;
191         }
192         else
193         {
194           try
195           {
196             summaryRowData[colCounter++] = (field.getDataColumnClass() == Integer.class) ? Integer
197                     .valueOf(fieldData)
198                     : (field.getDataColumnClass() == Double.class) ? Double
199                             .valueOf(fieldData) : fieldData;
200           } catch (Exception e)
201           {
202             e.printStackTrace();
203               System.out.println("offending value:" + fieldData);
204           }
205         }
206       } catch (Exception e)
207       {
208         // e.printStackTrace();
209       }
210     }
211
212     final String primaryKey1 = primaryKey;
213
214     final Object[] summaryRowData1 = summaryRowData;
215     return new FTSData()
216     {
217       @Override
218       public Object[] getSummaryData()
219       {
220         return summaryRowData1;
221       }
222
223       @Override
224       public Object getPrimaryKey()
225       {
226         return primaryKey1;
227       }
228
229       /**
230        * Returns a string representation of this object;
231        */
232       @Override
233       public String toString()
234       {
235         StringBuilder summaryFieldValues = new StringBuilder();
236         for (Object summaryField : summaryRowData1)
237         {
238           summaryFieldValues.append(
239                   summaryField == null ? " " : summaryField.toString())
240                   .append("\t");
241         }
242         return summaryFieldValues.toString();
243       }
244
245       /**
246        * Returns hash code value for this object
247        */
248       @Override
249       public int hashCode()
250       {
251         return Objects.hash(primaryKey1, this.toString());
252       }
253     };
254   }
255
256
257   public static FTSRestClientI getInstance()
258   {
259     if (instance == null)
260     {
261       instance = new UniProtFTSRestClient();
262     }
263     return instance;
264   }
265
266   @Override
267   public String getColumnDataConfigFileName()
268   {
269     return "/fts/uniprot_data_columns.txt";
270   }
271
272 }