refactored das sequence source creation code to the implementor of the das source...
[jalview.git] / src / jalview / ws / SequenceFetcher.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)\r
3  * Copyright (C) 2011 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle\r
4  * \r
5  * This file is part of Jalview.\r
6  * \r
7  * Jalview is free software: you can redistribute it and/or\r
8  * modify it under the terms of the GNU General Public License \r
9  * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\r
10  * \r
11  * Jalview is distributed in the hope that it will be useful, but \r
12  * WITHOUT ANY WARRANTY; without even the implied warranty \r
13  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR \r
14  * PURPOSE.  See the GNU General Public License for more details.\r
15  * \r
16  * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.\r
17  */\r
18 package jalview.ws;\r
19 \r
20 import jalview.datamodel.Alignment;\r
21 import jalview.datamodel.AlignmentI;\r
22 import jalview.datamodel.DBRefSource;\r
23 import jalview.datamodel.SequenceI;\r
24 import jalview.ws.dbsources.das.api.jalviewSourceI;\r
25 import jalview.ws.seqfetcher.ASequenceFetcher;\r
26 import jalview.ws.seqfetcher.DbSourceProxy;\r
27 \r
28 import java.util.ArrayList;\r
29 import java.util.Enumeration;\r
30 import java.util.List;\r
31 import java.util.Vector;\r
32 \r
33 /**\r
34  * This is the the concrete implementation of the sequence retrieval interface\r
35  * and abstract class in jalview.ws.seqfetcher. This implements the run-time\r
36  * discovery of sequence database clients, and provides a hardwired main for\r
37  * testing all registered handlers.\r
38  * \r
39  */\r
40 public class SequenceFetcher extends ASequenceFetcher\r
41 {\r
42   /**\r
43    * Thread safe construction of database proxies TODO: extend to a configurable\r
44    * database plugin mechanism where classes are instantiated by reflection and\r
45    * queried for their DbRefSource and version association.\r
46    * \r
47    */\r
48   public SequenceFetcher()\r
49   {\r
50     addDBRefSourceImpl(jalview.ws.dbsources.EmblSource.class);\r
51     addDBRefSourceImpl(jalview.ws.dbsources.EmblCdsSouce.class);\r
52     addDBRefSourceImpl(jalview.ws.dbsources.Uniprot.class);\r
53     addDBRefSourceImpl(jalview.ws.dbsources.UnprotName.class);\r
54     addDBRefSourceImpl(jalview.ws.dbsources.Pdb.class);\r
55     addDBRefSourceImpl(jalview.ws.dbsources.PfamFull.class);\r
56     addDBRefSourceImpl(jalview.ws.dbsources.PfamSeed.class); // ensures Seed\r
57     // alignment is\r
58     // 'default' for\r
59     // PFAM\r
60     registerDasSequenceSources();\r
61   }\r
62 \r
63   /**\r
64    * return an ordered list of database sources suitable for using in a GUI\r
65    * element\r
66    */\r
67   public String[] getOrderedSupportedSources()\r
68   {\r
69     String[] srcs = this.getSupportedDb();\r
70     ArrayList dassrc = new ArrayList(), nondas = new ArrayList();\r
71     for (int i = 0; i < srcs.length; i++)\r
72     {\r
73       String nm = getSourceProxy(srcs[i]).getDbName();\r
74       if (getSourceProxy(srcs[i]) instanceof jalview.ws.dbsources.das.datamodel.DasSequenceSource)\r
75       {\r
76         if (nm.startsWith("das:"))\r
77         {\r
78           nm = nm.substring(4);\r
79         }\r
80         dassrc.add(new String[]\r
81         { srcs[i], nm.toUpperCase() });\r
82       }\r
83       else\r
84       {\r
85         nondas.add(new String[]\r
86         { srcs[i], nm.toUpperCase() });\r
87       }\r
88     }\r
89     Object[] sorted = nondas.toArray();\r
90     String[] tosort = new String[sorted.length];\r
91     nondas.clear();\r
92     for (int j = 0; j < sorted.length; j++)\r
93     {\r
94       tosort[j] = ((String[]) sorted[j])[1];\r
95     }\r
96     jalview.util.QuickSort.sort(tosort, sorted);\r
97     int i = 0;\r
98     for (int j = sorted.length - 1; j >= 0; j--, i++)\r
99     {\r
100       srcs[i] = ((String[]) sorted[j])[0];\r
101       sorted[j] = null;\r
102     }\r
103 \r
104     sorted = dassrc.toArray();\r
105     tosort = new String[sorted.length];\r
106     dassrc.clear();\r
107     for (int j = 0; j < sorted.length; j++)\r
108     {\r
109       tosort[j] = ((String[]) sorted[j])[1];\r
110     }\r
111     jalview.util.QuickSort.sort(tosort, sorted);\r
112     for (int j = sorted.length - 1; j >= 0; j--, i++)\r
113     {\r
114       srcs[i] = ((String[]) sorted[j])[0];\r
115       sorted[j] = null;\r
116     }\r
117     return srcs;\r
118   }\r
119 \r
120   /**\r
121    * simple run method to test dbsources.\r
122    * \r
123    * @param argv\r
124    */\r
125   public static void main(String[] argv)\r
126   {\r
127     AlignmentI ds = null;\r
128     Vector noProds = new Vector();\r
129     String usage = "SequenceFetcher.main [<DBNAME> <ACCNO>]\n"\r
130             + "With no arguments, all DbSources will be queried with their test Accession number.\n"\r
131             + "If given two arguments, SequenceFetcher will try to find the DbFetcher corresponding to <DBNAME> and retrieve <ACCNO> from it.";\r
132     if (argv != null && argv.length > 0)\r
133     {\r
134       DbSourceProxy sp = new SequenceFetcher().getSourceProxy(argv[0]);\r
135       if (sp != null)\r
136       {\r
137         AlignmentI al = null;\r
138         try\r
139         {\r
140           al = sp.getSequenceRecords(argv[1]);\r
141         } catch (Exception e)\r
142         {\r
143           e.printStackTrace();\r
144           System.err.println("Error when retrieving " + argv[1] + " from "\r
145                   + argv[0] + "\nUsage: " + usage);\r
146         }\r
147         SequenceI[] prod = al.getSequencesArray();\r
148         if (al != null)\r
149         {\r
150           for (int p = 0; p < prod.length; p++)\r
151           {\r
152             System.out.println("Prod " + p + ": "\r
153                     + prod[p].getDisplayId(true) + " : "\r
154                     + prod[p].getDescription());\r
155           }\r
156         }\r
157         return;\r
158       }\r
159       else\r
160       {\r
161         System.err.println("Can't resolve " + argv[0]\r
162                 + " as a database name. Allowed values are :\n"\r
163                 + new SequenceFetcher().getSupportedDb());\r
164       }\r
165       System.out.println(usage);\r
166     }\r
167     ASequenceFetcher sfetcher = new SequenceFetcher();\r
168     String[] dbSources = sfetcher.getSupportedDb();\r
169     for (int dbsource = 0; dbsource < dbSources.length; dbsource++)\r
170     {\r
171       String db = dbSources[dbsource];\r
172       // skip me\r
173       if (db.equals(DBRefSource.PDB))\r
174         continue;\r
175       DbSourceProxy sp = sfetcher.getSourceProxy(db);\r
176       System.out.println("Source: " + sp.getDbName() + " (" + db\r
177               + "): retrieving test:" + sp.getTestQuery());\r
178       AlignmentI al = null;\r
179       try\r
180       {\r
181         al = sp.getSequenceRecords(sp.getTestQuery());\r
182         if (al != null && al.getHeight() > 0\r
183                 && sp.getDbSourceProperties() != null)\r
184         {\r
185           boolean dna = sp.getDbSourceProperties().containsKey(\r
186                   DBRefSource.DNACODINGSEQDB)\r
187                   || sp.getDbSourceProperties().containsKey(\r
188                           DBRefSource.DNASEQDB)\r
189                   || sp.getDbSourceProperties().containsKey(\r
190                           DBRefSource.CODINGSEQDB);\r
191           // try and find products\r
192           String types[] = jalview.analysis.CrossRef.findSequenceXrefTypes(\r
193                   dna, al.getSequencesArray());\r
194           if (types != null)\r
195           {\r
196             System.out.println("Xref Types for: " + (dna ? "dna" : "prot"));\r
197             for (int t = 0; t < types.length; t++)\r
198             {\r
199               System.out.println("Type: " + types[t]);\r
200               SequenceI[] prod = jalview.analysis.CrossRef\r
201                       .findXrefSequences(al.getSequencesArray(), dna,\r
202                               types[t]).getSequencesArray();\r
203               System.out.println("Found "\r
204                       + ((prod == null) ? "no" : "" + prod.length)\r
205                       + " products");\r
206               if (prod != null)\r
207               {\r
208                 for (int p = 0; p < prod.length; p++)\r
209                 {\r
210                   System.out.println("Prod " + p + ": "\r
211                           + prod[p].getDisplayId(true));\r
212                 }\r
213               }\r
214             }\r
215           }\r
216           else\r
217           {\r
218             noProds.addElement((dna ? new Object[]\r
219             { al, al } : new Object[]\r
220             { al }));\r
221           }\r
222 \r
223         }\r
224       } catch (Exception ex)\r
225       {\r
226         System.out.println("ERROR:Failed to retrieve test query.");\r
227         ex.printStackTrace(System.out);\r
228       }\r
229       if (al == null)\r
230       {\r
231         System.out.println("ERROR:No alignment retrieved.");\r
232         StringBuffer raw = sp.getRawRecords();\r
233         if (raw != null)\r
234           System.out.println(raw.toString());\r
235         else\r
236           System.out.println("ERROR:No Raw results.");\r
237       }\r
238       else\r
239       {\r
240         System.out.println("Retrieved " + al.getHeight() + " sequences.");\r
241         for (int s = 0; s < al.getHeight(); s++)\r
242         {\r
243           SequenceI sq = al.getSequenceAt(s);\r
244           while (sq.getDatasetSequence() != null)\r
245           {\r
246             sq = sq.getDatasetSequence();\r
247 \r
248           }\r
249           if (ds == null)\r
250           {\r
251             ds = new Alignment(new SequenceI[]\r
252             { sq });\r
253 \r
254           }\r
255           else\r
256           {\r
257             ds.addSequence(sq);\r
258           }\r
259         }\r
260       }\r
261       System.out.flush();\r
262       System.err.flush();\r
263 \r
264     }\r
265     if (noProds.size() > 0)\r
266     {\r
267       Enumeration ts = noProds.elements();\r
268       while (ts.hasMoreElements())\r
269 \r
270       {\r
271         Object[] typeSq = (Object[]) ts.nextElement();\r
272         boolean dna = (typeSq.length > 1);\r
273         AlignmentI al = (AlignmentI) typeSq[0];\r
274         System.out.println("Trying getProducts for "\r
275                 + al.getSequenceAt(0).getDisplayId(true));\r
276         System.out.println("Search DS Xref for: " + (dna ? "dna" : "prot"));\r
277         // have a bash at finding the products amongst all the retrieved\r
278         // sequences.\r
279         SequenceI[] seqs = al.getSequencesArray();\r
280         Alignment prodal = jalview.analysis.CrossRef.findXrefSequences(\r
281                 seqs, dna, null, ds);\r
282         System.out.println("Found "\r
283                 + ((prodal == null) ? "no" : "" + prodal.getHeight())\r
284                 + " products");\r
285         if (prodal != null)\r
286         {\r
287           SequenceI[] prod = prodal.getSequencesArray(); // note\r
288           // should\r
289           // test\r
290           // rather\r
291           // than\r
292           // throw\r
293           // away\r
294           // codon\r
295           // mapping\r
296           // (if\r
297           // present)\r
298           for (int p = 0; p < prod.length; p++)\r
299           {\r
300             System.out.println("Prod " + p + ": "\r
301                     + prod[p].getDisplayId(true));\r
302           }\r
303         }\r
304       }\r
305 \r
306     }\r
307   }\r
308 \r
309   /**\r
310    * query the currently defined DAS source registry for sequence sources and\r
311    * add a DasSequenceSource instance for each source to the SequenceFetcher\r
312    * source list.\r
313    */\r
314   public void registerDasSequenceSources()\r
315   {\r
316     // TODO: define a context as a registry provider (either desktop,\r
317     // jalview.bin.cache, or something else).\r
318     for (jalviewSourceI source : jalview.bin.Cache.getDasSourceRegistry().getSources())\r
319     {\r
320       if (source.isSequenceSource())\r
321       {\r
322         List<DbSourceProxy> dassources = source.getSequenceSourceProxies();\r
323         for (DbSourceProxy seqsrc : dassources)\r
324         {\r
325           addDbRefSourceImpl(seqsrc);\r
326         }\r
327       }\r
328     }\r
329   }\r
330 }\r