JAL-1563 JAL-2091 Added generic pagination for FTS Service, pagination for PDB FTS...
[jalview.git] / src / jalview / fts / core / FTSRestClient.java
1 package jalview.fts.core;
2
3 import jalview.fts.api.FTSDataColumnI;
4 import jalview.fts.api.FTSDataColumnI.FTSDataColumnGroupI;
5 import jalview.fts.api.FTSRestClientI;
6 import jalview.util.MessageManager;
7
8 import java.io.BufferedReader;
9 import java.io.IOException;
10 import java.io.InputStream;
11 import java.io.InputStreamReader;
12 import java.util.ArrayList;
13 import java.util.Collection;
14 import java.util.Objects;
15
16 /**
17  * Base class providing implementation for common methods defined in
18  * FTSRestClientI
19  * 
20  * @author tcnofoegbu
21  * 
22  * @note implementations MUST be accessed as a singleton.
23  */
24 public abstract class FTSRestClient implements FTSRestClientI
25 {
26   protected Collection<FTSDataColumnI> dataColumns = new ArrayList<FTSDataColumnI>();
27
28   protected Collection<FTSDataColumnGroupI> dataColumnGroups = new ArrayList<FTSDataColumnGroupI>();
29
30   protected Collection<FTSDataColumnI> searchableDataColumns = new ArrayList<FTSDataColumnI>();
31
32   protected Collection<FTSDataColumnI> defaulDisplayedDataColumns = new ArrayList<FTSDataColumnI>();
33
34   protected FTSDataColumnI primaryKeyColumn;
35
36   private String primaryKeyColumnCode = null;
37
38   private int defaultResponsePageSize = 100;
39
40   protected FTSRestClient()
41   {
42
43   }
44
45   public void parseDataColumnsConfigFile()
46   {
47     String fileName = getColumnDataConfigFileName();
48     
49     InputStream in = getClass().getResourceAsStream(fileName); 
50     
51     try (BufferedReader br = new BufferedReader(new InputStreamReader(in)))
52     {
53       String line;
54       while ((line = br.readLine()) != null)
55       {
56         final String[] lineData = line.split(";");
57         try
58         {
59           if (lineData.length == 2)
60           {
61             if (lineData[0].equalsIgnoreCase("_data_column.primary_key"))
62             {
63               primaryKeyColumnCode = lineData[1];
64             }
65             if (lineData[0]
66                     .equalsIgnoreCase("_data_column.default_response_page_size"))
67             {
68               defaultResponsePageSize = Integer.valueOf(lineData[1]);
69             }
70           }
71           else if (lineData.length == 3)
72           {
73             dataColumnGroups.add(new FTSDataColumnGroupI()
74             {
75               @Override
76               public String getID()
77               {
78                 return lineData[0];
79               }
80
81               @Override
82               public String getName()
83               {
84                 return lineData[1];
85               }
86
87               @Override
88               public int getSortOrder()
89               {
90                 return Integer.valueOf(lineData[2]);
91               }
92
93               @Override
94               public String toString()
95               {
96                 return lineData[1];
97               }
98
99               @Override
100               public int hashCode()
101               {
102                 return Objects.hash(this.getID(), this.getName(),
103                         this.getSortOrder());
104               }
105
106               @Override
107               public boolean equals(Object otherObject)
108               {
109                 FTSDataColumnGroupI that = (FTSDataColumnGroupI) otherObject;
110                 return this.getID().equals(that.getID())
111                         && this.getName().equals(that.getName())
112                         && this.getSortOrder() == that.getSortOrder();
113               }
114             });
115           }
116           else if (lineData.length > 6)
117           {
118             FTSDataColumnI dataCol = new FTSDataColumnI()
119             {
120               @Override
121               public String toString()
122               {
123                 return lineData[0];
124               }
125
126               @Override
127               public String getName()
128               {
129                 return lineData[0];
130               }
131
132               @Override
133               public String getCode()
134               {
135                 return lineData[1].split("\\|")[0];
136               }
137
138               @Override
139               public String getAltCode()
140               {
141                 return lineData[1].split("\\|").length > 1 ? lineData[1]
142                         .split("\\|")[1] : getCode();
143               }
144
145               @Override
146               public Class<?> getDataColumnClass()
147               {
148                 String classString = lineData[2];
149                 classString = classString.toUpperCase();
150                 switch (classString)
151                 {
152                 case "INT":
153                 case "INTEGER":
154                   return Integer.class;
155                 case "DOUBLE":
156                   return Double.class;
157                 case "STRING":
158                 default:
159                   return String.class;
160                 }
161               }
162
163               @Override
164               public FTSDataColumnGroupI getGroup()
165               {
166                 FTSDataColumnGroupI group = null;
167                 try
168                 {
169                   group = getDataColumnGroupById(lineData[3]);
170                 } catch (Exception e)
171                 {
172                   e.printStackTrace();
173                 }
174                 return group;
175               }
176
177               @Override
178               public int getMinWidth()
179               {
180                 return Integer.valueOf(lineData[4]);
181               }
182
183               @Override
184               public int getMaxWidth()
185               {
186                 return Integer.valueOf(lineData[5]);
187               }
188
189               @Override
190               public int getPreferredWidth()
191               {
192                 return Integer.valueOf(lineData[6]);
193               }
194
195               @Override
196               public boolean isPrimaryKeyColumn()
197               {
198                 return getName().equalsIgnoreCase(primaryKeyColumnCode)
199                         || getCode().equalsIgnoreCase(primaryKeyColumnCode);
200               }
201
202               @Override
203               public boolean isVisibleByDefault()
204               {
205                 return Boolean.valueOf(lineData[7]);
206               }
207
208               @Override
209               public boolean isSearchable()
210               {
211                 return Boolean.valueOf(lineData[8]);
212               }
213
214               @Override
215               public int hashCode()
216               {
217                 return Objects.hash(this.getName(), this.getCode(),
218                         this.getGroup());
219               }
220
221
222               @Override
223               public boolean equals(Object otherObject)
224               {
225                 FTSDataColumnI that = (FTSDataColumnI) otherObject;
226                 return this.getCode().equals(that.getCode())
227                         && this.getName().equals(that.getName())
228                         && this.getGroup().equals(that.getGroup());
229               }
230
231             };
232             dataColumns.add(dataCol);
233
234             if (dataCol.isSearchable())
235             {
236               searchableDataColumns.add(dataCol);
237             }
238
239             if (dataCol.isVisibleByDefault())
240             {
241               defaulDisplayedDataColumns.add(dataCol);
242             }
243
244           }
245           else
246           {
247             continue;
248           }
249         } catch (Exception e)
250         {
251           e.printStackTrace();
252         }
253       }
254       try
255       {
256         this.primaryKeyColumn = getDataColumnByNameOrCode(primaryKeyColumnCode);
257       } catch (Exception e)
258       {
259         e.printStackTrace();
260       }
261     } catch (IOException e)
262     {
263       e.printStackTrace();
264     }
265   }
266
267   @Override
268   public int getPrimaryKeyColumIndex(
269           Collection<FTSDataColumnI> wantedFields, boolean hasRefSeq)
270           throws Exception
271   {
272
273     // If a reference sequence is attached then start counting from 1 else
274     // start from zero
275     int pdbFieldIndexCounter = hasRefSeq ? 1 : 0;
276
277     for (FTSDataColumnI field : wantedFields)
278     {
279       if (field.isPrimaryKeyColumn())
280       {
281         break; // Once PDB Id index is determined exit iteration
282       }
283       ++pdbFieldIndexCounter;
284     }
285     return pdbFieldIndexCounter;
286   }
287
288   @Override
289   public String getDataColumnsFieldsAsCommaDelimitedString(
290           Collection<FTSDataColumnI> dataColumnFields)
291   {
292     String result = "";
293     if (dataColumnFields != null && !dataColumnFields.isEmpty())
294     {
295       StringBuilder returnedFields = new StringBuilder();
296       for (FTSDataColumnI field : dataColumnFields)
297       {
298         returnedFields.append(",").append(field.getCode());
299       }
300       returnedFields.deleteCharAt(0);
301       result = returnedFields.toString();
302     }
303     return result;
304   }
305
306
307   @Override
308   public Collection<FTSDataColumnI> getAllFTSDataColumns()
309   {
310     if (dataColumns == null || dataColumns.isEmpty())
311     {
312       parseDataColumnsConfigFile();
313     }
314     return dataColumns;
315   }
316
317   @Override
318   public Collection<FTSDataColumnI> getSearchableDataColumns()
319   {
320     if (searchableDataColumns == null || searchableDataColumns.isEmpty())
321     {
322       parseDataColumnsConfigFile();
323     }
324     return searchableDataColumns;
325   }
326
327   @Override
328   public Collection<FTSDataColumnI> getAllDefaulDisplayedDataColumns()
329   {
330     if (defaulDisplayedDataColumns == null
331             || defaulDisplayedDataColumns.isEmpty())
332     {
333       parseDataColumnsConfigFile();
334     }
335     return defaulDisplayedDataColumns;
336   }
337
338   @Override
339   public FTSDataColumnI getPrimaryKeyColumn()
340   {
341     if (defaulDisplayedDataColumns == null
342             || defaulDisplayedDataColumns.isEmpty())
343     {
344       parseDataColumnsConfigFile();
345     }
346     return primaryKeyColumn;
347   }
348
349   @Override
350   public FTSDataColumnI getDataColumnByNameOrCode(String nameOrCode)
351           throws Exception
352   {
353     if (dataColumns == null || dataColumns.isEmpty())
354     {
355       parseDataColumnsConfigFile();
356     }
357     for (FTSDataColumnI column : dataColumns)
358     {
359       if (column.getName().equalsIgnoreCase(nameOrCode)
360               || column.getCode().equalsIgnoreCase(nameOrCode))
361       {
362         return column;
363       }
364     }
365     throw new Exception("Couldn't find data column with name : "
366             + nameOrCode);
367   }
368
369   @Override
370   public FTSDataColumnGroupI getDataColumnGroupById(String id)
371           throws Exception
372   {
373     if (dataColumns == null || dataColumns.isEmpty())
374     {
375       parseDataColumnsConfigFile();
376     }
377     for (FTSDataColumnGroupI columnGroup : dataColumnGroups)
378     {
379       if (columnGroup.getID().equalsIgnoreCase(id))
380       {
381         return columnGroup;
382       }
383     }
384     throw new Exception("Couldn't find data column group with id : " + id);
385   }
386
387   public String getMessageByHTTPStatusCode(int code, String service)
388   {
389     String message = "";
390     switch (code)
391     {
392     case 400:
393       message = MessageManager
394               .getString("exception.bad_request");
395       break;
396       
397     case 410:
398       message = MessageManager.formatMessage(
399               "exception.fts_rest_service_no_longer_available", service);
400       break;
401     case 403:
402     case 404:
403       message = MessageManager.getString("exception.resource_not_be_found");
404       break;
405     case 408:
406     case 409:
407     case 500:
408     case 501:
409     case 502:
410     case 504:
411     case 505:
412       message = MessageManager.getString("exception.fts_server_error");
413       break;
414     case 503:
415       message = MessageManager.getString("exception.service_not_available");
416       break;
417     default:
418       break;
419     }
420     return message;
421   }
422
423   protected String getResourceFile(String fileName)
424   {
425     String result = "";
426     try
427     {
428       result = getClass().getResource(fileName).getFile();
429     } catch (Exception e)
430     {
431       e.printStackTrace();
432     }
433     return result;
434
435   }
436
437   @Override
438   public int getDefaultResponsePageSize()
439   {
440     if (dataColumns == null || dataColumns.isEmpty())
441     {
442       parseDataColumnsConfigFile();
443     }
444     return defaultResponsePageSize;
445   }
446
447 }