JAL-2738 copy to spikes/mungo
[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].equalsIgnoreCase(
86                     "_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
162                         ? lineData[1].split("\\|")[1]
163                         : getCode();
164               }
165
166               @Override
167               public DataTypeI getDataType()
168               {
169                 final String[] dataTypeString = lineData[2].split("\\|");
170                 final String classString = dataTypeString[0].toUpperCase();
171
172                 return new DataTypeI()
173                 {
174
175                   @Override
176                   public boolean isFormtted()
177                   {
178                     if (dataTypeString.length > 1
179                             && dataTypeString[1] != null)
180                     {
181                       switch (dataTypeString[1].toUpperCase())
182                       {
183                       case "T":
184                       case "TRUE":
185                         return true;
186                       case "F":
187                       case "False":
188                       default:
189                         return false;
190                       }
191                     }
192                     return false;
193                   }
194
195                   @Override
196                   public int getSignificantFigures()
197                   {
198                     if (dataTypeString.length > 2
199                             && dataTypeString[2] != null)
200                     {
201                       return Integer.valueOf(dataTypeString[2]);
202                     }
203                     return 0;
204                   }
205
206                   @Override
207                   public Class getDataTypeClass()
208                   {
209                     switch (classString)
210                     {
211                     case "INT":
212                     case "INTEGER":
213                       return Integer.class;
214                     case "DOUBLE":
215                       return Double.class;
216                     case "STRING":
217                     default:
218                       return String.class;
219                     }
220                   }
221                 };
222
223               }
224
225               @Override
226               public FTSDataColumnGroupI getGroup()
227               {
228                 FTSDataColumnGroupI group = null;
229                 try
230                 {
231                   group = getDataColumnGroupById(lineData[3]);
232                 } catch (Exception e)
233                 {
234                   e.printStackTrace();
235                 }
236                 return group;
237               }
238
239               @Override
240               public int getMinWidth()
241               {
242                 return Integer.valueOf(lineData[4]);
243               }
244
245               @Override
246               public int getMaxWidth()
247               {
248                 return Integer.valueOf(lineData[5]);
249               }
250
251               @Override
252               public int getPreferredWidth()
253               {
254                 return Integer.valueOf(lineData[6]);
255               }
256
257               @Override
258               public boolean isPrimaryKeyColumn()
259               {
260                 return getName().equalsIgnoreCase(primaryKeyColumnCode)
261                         || getCode().equalsIgnoreCase(primaryKeyColumnCode);
262               }
263
264               @Override
265               public boolean isVisibleByDefault()
266               {
267                 return Boolean.valueOf(lineData[7]);
268               }
269
270               @Override
271               public boolean isSearchable()
272               {
273                 return Boolean.valueOf(lineData[8]);
274               }
275
276               @Override
277               public int hashCode()
278               {
279                 return Objects.hash(this.getName(), this.getCode(),
280                         this.getGroup());
281               }
282
283               @Override
284               public boolean equals(Object otherObject)
285               {
286                 FTSDataColumnI that = (FTSDataColumnI) otherObject;
287                 return this.getCode().equals(that.getCode())
288                         && this.getName().equals(that.getName())
289                         && this.getGroup().equals(that.getGroup());
290               }
291
292             };
293             dataColumns.add(dataCol);
294
295             if (dataCol.isSearchable())
296             {
297               searchableDataColumns.add(dataCol);
298             }
299
300             if (dataCol.isVisibleByDefault())
301             {
302               defaulDisplayedDataColumns.add(dataCol);
303             }
304
305           }
306           else
307           {
308             continue;
309           }
310         } catch (Exception e)
311         {
312           e.printStackTrace();
313         }
314       }
315       try
316       {
317         this.primaryKeyColumn = getDataColumnByNameOrCode(
318                 primaryKeyColumnCode);
319       } catch (Exception e)
320       {
321         e.printStackTrace();
322       }
323     } catch (IOException e)
324     {
325       e.printStackTrace();
326     }
327   }
328
329   @Override
330   public int getPrimaryKeyColumIndex(
331           Collection<FTSDataColumnI> wantedFields, boolean hasRefSeq)
332           throws Exception
333   {
334
335     // If a reference sequence is attached then start counting from 1 else
336     // start from zero
337     int pdbFieldIndexCounter = hasRefSeq ? 1 : 0;
338
339     for (FTSDataColumnI field : wantedFields)
340     {
341       if (field.isPrimaryKeyColumn())
342       {
343         break; // Once PDB Id index is determined exit iteration
344       }
345       ++pdbFieldIndexCounter;
346     }
347     return pdbFieldIndexCounter;
348   }
349
350   @Override
351   public String getDataColumnsFieldsAsCommaDelimitedString(
352           Collection<FTSDataColumnI> dataColumnFields)
353   {
354     String result = "";
355     if (dataColumnFields != null && !dataColumnFields.isEmpty())
356     {
357       StringBuilder returnedFields = new StringBuilder();
358       for (FTSDataColumnI field : dataColumnFields)
359       {
360         returnedFields.append(",").append(field.getCode());
361       }
362       returnedFields.deleteCharAt(0);
363       result = returnedFields.toString();
364     }
365     return result;
366   }
367
368   @Override
369   public Collection<FTSDataColumnI> getAllFTSDataColumns()
370   {
371     if (dataColumns == null || dataColumns.isEmpty())
372     {
373       parseDataColumnsConfigFile();
374     }
375     return dataColumns;
376   }
377
378   @Override
379   public Collection<FTSDataColumnI> getSearchableDataColumns()
380   {
381     if (searchableDataColumns == null || searchableDataColumns.isEmpty())
382     {
383       parseDataColumnsConfigFile();
384     }
385     return searchableDataColumns;
386   }
387
388   @Override
389   public Collection<FTSDataColumnI> getAllDefaultDisplayedFTSDataColumns()
390   {
391     if (defaulDisplayedDataColumns == null
392             || defaulDisplayedDataColumns.isEmpty())
393     {
394       parseDataColumnsConfigFile();
395     }
396     return defaulDisplayedDataColumns;
397   }
398
399   @Override
400   public FTSDataColumnI getPrimaryKeyColumn()
401   {
402     if (defaulDisplayedDataColumns == null
403             || defaulDisplayedDataColumns.isEmpty())
404     {
405       parseDataColumnsConfigFile();
406     }
407     return primaryKeyColumn;
408   }
409
410   @Override
411   public FTSDataColumnI getDataColumnByNameOrCode(String nameOrCode)
412           throws Exception
413   {
414     if (dataColumns == null || dataColumns.isEmpty())
415     {
416       parseDataColumnsConfigFile();
417     }
418     for (FTSDataColumnI column : dataColumns)
419     {
420       if (column.getName().equalsIgnoreCase(nameOrCode)
421               || column.getCode().equalsIgnoreCase(nameOrCode))
422       {
423         return column;
424       }
425     }
426     throw new Exception(
427             "Couldn't find data column with name : " + nameOrCode);
428   }
429
430   @Override
431   public FTSDataColumnGroupI getDataColumnGroupById(String id)
432           throws Exception
433   {
434     if (dataColumns == null || dataColumns.isEmpty())
435     {
436       parseDataColumnsConfigFile();
437     }
438     for (FTSDataColumnGroupI columnGroup : dataColumnGroups)
439     {
440       if (columnGroup.getID().equalsIgnoreCase(id))
441       {
442         return columnGroup;
443       }
444     }
445     throw new Exception("Couldn't find data column group with id : " + id);
446   }
447
448   public String getMessageByHTTPStatusCode(int code, String service)
449   {
450     String message = "";
451     switch (code)
452     {
453     case 400:
454       message = MessageManager.getString("exception.bad_request");
455       break;
456
457     case 410:
458       message = MessageManager.formatMessage(
459               "exception.fts_rest_service_no_longer_available", service);
460       break;
461     case 403:
462     case 404:
463       message = MessageManager.getString("exception.resource_not_be_found");
464       break;
465     case 408:
466     case 409:
467     case 500:
468     case 501:
469     case 502:
470     case 504:
471     case 505:
472       message = MessageManager.formatMessage("exception.fts_server_error",
473               service);
474       break;
475     case 503:
476       message = MessageManager.getString("exception.service_not_available");
477       break;
478     default:
479       break;
480     }
481     return message;
482   }
483
484   protected String getResourceFile(String fileName)
485   {
486     String result = "";
487     try
488     {
489       result = getClass().getResource(fileName).getFile();
490     } catch (Exception e)
491     {
492       e.printStackTrace();
493     }
494     return result;
495
496   }
497
498   @Override
499   public int getDefaultResponsePageSize()
500   {
501     if (dataColumns == null || dataColumns.isEmpty())
502     {
503       parseDataColumnsConfigFile();
504     }
505     return defaultResponsePageSize;
506   }
507
508 }