JAL-3829 refactored FilterOption provider to the StructureChooserQuerySource implemen...
[jalview.git] / src / jalview / gui / structurechooser / StructureChooserQuerySource.java
1 package jalview.gui.structurechooser;
2
3 import java.util.Collection;
4 import java.util.List;
5 import java.util.Objects;
6 import java.util.Vector;
7
8 import javax.swing.JTable;
9 import javax.swing.table.TableModel;
10
11 import jalview.datamodel.DBRefEntry;
12 import jalview.datamodel.PDBEntry;
13 import jalview.datamodel.SequenceI;
14 import jalview.fts.api.FTSData;
15 import jalview.fts.api.FTSDataColumnI;
16 import jalview.fts.api.FTSRestClientI;
17 import jalview.fts.core.FTSDataColumnPreferences;
18 import jalview.fts.core.FTSRestRequest;
19 import jalview.fts.core.FTSRestResponse;
20 import jalview.jbgui.FilterOption;
21
22 /**
23  * logic for querying sources of structural data for structures of sequences
24  * 
25  * @author jprocter
26  *
27  * @param <T>
28  */
29 public abstract class StructureChooserQuerySource
30 {
31   protected FTSRestRequest lastPdbRequest;
32
33   protected FTSRestClientI pdbRestClient;
34
35   protected FTSDataColumnPreferences docFieldPrefs;
36
37   /**
38    * max length of a GET URL (probably :( )
39    */
40   protected static int MAX_QLENGTH = 7820;
41
42   public StructureChooserQuerySource()
43   {
44   }
45
46   public static StructureChooserQuerySource getPDBfts()
47   {
48           return new PDBStructureChooserQuerySource();
49   }
50
51   public static StructureChooserQuerySource getTDBfts()
52   {
53     return new ThreeDBStructureChooserQuerySource();
54   }
55
56   public FTSDataColumnPreferences getDocFieldPrefs()
57   {
58     return docFieldPrefs;
59   }
60
61   public void setDocFieldPrefs(FTSDataColumnPreferences docFieldPrefs)
62   {
63     this.docFieldPrefs = docFieldPrefs;
64   }
65
66   public FTSDataColumnPreferences getInitialFieldPreferences()
67   {
68     return docFieldPrefs;
69   }
70
71
72   /**
73    * Builds a query string for a given sequences using its DBRef entries
74    * 
75    * @param seq
76    *          the sequences to build a query for
77    * @return the built query string
78    */
79
80   public abstract String buildQuery(SequenceI seq);
81   
82
83   /**
84    * Remove the following special characters from input string +, -, &, !, (, ),
85    * {, }, [, ], ^, ", ~, *, ?, :, \
86    * 
87    * @param seqName
88    * @return
89    */
90   public static String sanitizeSeqName(String seqName)
91   {
92     Objects.requireNonNull(seqName);
93     return seqName.replaceAll("\\[\\d*\\]", "")
94             .replaceAll("[^\\dA-Za-z|_]", "").replaceAll("\\s+", "+");
95   }
96
97   /**
98    * Ensures sequence ref names are not less than 3 characters and does not
99    * contain a database name
100    * 
101    * @param seqName
102    * @return
103    */
104   static boolean isValidSeqName(String seqName)
105   {
106     // System.out.println("seqName : " + seqName);
107     String ignoreList = "pdb,uniprot,swiss-prot";
108     if (seqName.length() < 3)
109     {
110       return false;
111     }
112     if (seqName.contains(":"))
113     {
114       return false;
115     }
116     seqName = seqName.toLowerCase();
117     for (String ignoredEntry : ignoreList.split(","))
118     {
119       if (seqName.contains(ignoredEntry))
120       {
121         return false;
122       }
123     }
124     return true;
125   }
126
127   static String getDBRefId(DBRefEntry dbRef)
128   {
129     String ref = dbRef.getAccessionId().replaceAll("GO:", "");
130     return ref;
131   }
132
133   static PDBEntry getFindEntry(String id, Vector<PDBEntry> pdbEntries)
134   {
135     Objects.requireNonNull(id);
136     Objects.requireNonNull(pdbEntries);
137     PDBEntry foundEntry = null;
138     for (PDBEntry entry : pdbEntries)
139     {
140       if (entry.getId().equalsIgnoreCase(id))
141       {
142         return entry;
143       }
144     }
145     return foundEntry;
146   }
147
148   /**
149    * FTSRestClient specific query builder to recover associated structure data
150    * records for a sequence
151    * 
152    * @param seq
153    *          - seq to generate a query for
154    * @param wantedFields
155    *          - fields to retrieve
156    * @param selectedFilterOpt
157    *          - criterion for ranking results (e.g. resolution)
158    * @param b
159    *          - sort ascending or descending
160    * @return
161    * @throws Exception
162    */
163   public abstract FTSRestResponse fetchStructuresMetaData(SequenceI seq,
164           Collection<FTSDataColumnI> wantedFields,
165           FilterOption selectedFilterOpt, boolean b) throws Exception;
166
167   /**
168    * FTSRestClient specific query builder to pick top ranked entry from a
169    * fetchStructuresMetaData query
170    * 
171    * @param seq
172    *          - seq to generate a query for
173    * @param wantedFields
174    *          - fields to retrieve
175    * @param selectedFilterOpt
176    *          - criterion for ranking results (e.g. resolution)
177    * @param b
178    *          - sort ascending or descending
179    * @return
180    * @throws Exception
181    */
182   public abstract FTSRestResponse selectFirstRankedQuery(SequenceI seq,
183           Collection<FTSDataColumnI> wantedFields, String fieldToFilterBy,
184           boolean b) throws Exception;
185
186   /**
187    * 
188    * @param discoveredStructuresSet
189    * @return the table model for the given result set for this engine
190    */
191   public TableModel getTableModel(
192           Collection<FTSData> discoveredStructuresSet)
193   {
194     return FTSRestResponse.getTableModel(lastPdbRequest,
195             discoveredStructuresSet);
196   }
197
198   public abstract PDBEntry[] collectSelectedRows(JTable restable,
199           int[] selectedRows, List<SequenceI> selectedSeqsToView);
200
201   /**
202    * @param VIEWS_FILTER
203    *          - a String key that can be used by the caller to tag the returned filter
204    *          options to distinguish them in a collection
205    * @return list of FilterOption - convention is that the last one in the list
206    *         will be constructed with 'addSeparator==true'
207    */
208   public abstract List<FilterOption> getAvailableFilterOptions(String VIEWS_FILTER);
209 }