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